使用Logstash工具匯入sqlserver資料到elasticSearch及elk分散式日誌中心

星仔007發表於2023-01-15

首先記下這個筆記,Logstash工具匯入sqlserver資料到elasticSearch。

因為logstash使用java寫的,我本地開發是win11,所以javade jdk必須要安裝。具體安裝不介紹了,就是網上下個java8,不要去官網要賬號什麼的,不是java開發不太折騰,目前只用java8,記得JAVA_HOME配置一下環境變數。

java version "1.8.0_66"

Java(TM) SE Runtime Environment (build 1.8.0_66-b18)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b18, mixed mode)

從sqlserver拉取資料需要用到sqlserver 的jdbc驅動,我這裡是官網下載的sqljdbc_6.2.2.1_enu,沒用最新版本,個人認為java8不太合適什麼都最新的。

logstash使用的是7.0.0的版本,這裡遇到幾個問題。

換了幾個版本,7.0一下的起不來,8,0以上的也是起不來。

1.存放的目錄不能有空格,2.(我的坑)不該去github上下載版本,發現跑不起來。3.版本8.0以上的需要java11支援。

有了這兩個包(都是java的)後面就是配置了。首先我在ogstash-7.0.0\lib下面新建資料夾sqlserverdriver,去sqljdbc_6.2.2.1_enu\sqljdbc_6.2\enu資料夾下面複製了mssql-jdbc-6.2.2.jre8.jar檔案過來

下面就是操作logstash資料夾下面config下面檔案了。首先在jvm.options最下面加上許可權。

-Djava.library.path=E:\sqljdbc_6.2.2.1_enu\sqljdbc_6.2\enu\auth\x64

在config資料夾下面新建檔案sqlserver_update.conf檔案,複製下面的內容,每行基本有註釋就詳不說。

input {
  jdbc {
    jdbc_driver_library=>"E:\sqljdbc_6.2.2.1_enu\sqljdbc_6.2\enu/mssql-jdbc-6.2.2.jre8.jar"
    jdbc_driver_class => "com.microsoft.sqlserver.jdbc.SQLServerDriver"
    jdbc_connection_string => "jdbc:sqlserver://sqlserverIP:1433;databaseName=Reptile.NewsLetter"
    jdbc_user => "sa"
    jdbc_password => "密碼"
    #分頁且最大5萬次
    jdbc_paging_enabled => "true"
    jdbc_page_size => "50000"
    #時區按照東八
     jdbc_default_timezone =>"Asia/Shanghai"
     last_run_metadata_path => "E:\logstash-7.0.0\config\last_value_meta.txt"
     #啟用追蹤,則需要指定tracking_column,預設是timestamp()
     use_column_value => true
     # 如果 use_column_value 為真,需配置此引數. track 的資料庫 column 名,該 column 必須是遞增的. 一般是主鍵
     tracking_column => id
     #追蹤欄位的型別,目前只有數字(numeric)和時間型別(timestamp),預設是數字型別()
     tracking_column_type => numeric    
     #是否記錄上次執行結果, 如果為真,將會把上次執行到的 tracking_column 欄位的值記錄下來,儲存到 last_run_metadata_path 指定的檔案中
     record_last_run => true
     #statement_filepath => "E:\logstash-7.0.0\config\update.sql" sql可放到獨立檔案裡面去
     #表裡有時間也有時間戳 都可用
     statement => "SELECT * FROM [Reptile.NewsLetter].[dbo].[LivesItems] where id > :sql_last_value "
     schedule => "* * * * *"
     #是否清除 last_run_metadata_path 的記錄,如果為真那麼每次都相當於從頭開始查詢所有的資料庫記錄
     clean_run => false 
     #是否將 column 名稱轉小寫
     lowercase_column_names => false
  }
}
output {
   elasticsearch {
        hosts => ["http://my.es.com:9200"]   
        index => "nl_livesitem"
         user => "elastic"
         password => "changeme"
       }
}

上面的sql可以單獨放到一個檔案,增量更新可以透過實踐、時間戳、id,我這裡是id。

下面就是執行執行命令的時候了

bin\logstash -f config\sqlserver_update.conf ,上面設定的執行時corn是每分鐘一次。所以logstash會每分鐘去增量查詢同步到es。這個服務可以作為windows後臺服務,自行百度。

這裡es就能實時的拿到資料庫的資料。java的生態實在太好了。其實我們也可以透過net來寫這個同樣的共嗯,無非就是定時的查資料庫呼叫es介面的插入操作。如果公司很依賴這個的話建議還是自己寫,不管是版本還是配置還是升級這些都容易踩著坑。

 

簡單總結一下logstash同步資料的要點,首先配置好jdk驅動,其次就是配置檔案的配置。一個是bin、一個是config。總歸下來很簡單的。

下面簡單介紹下elk分散式日誌中心的搭建和使用

上面的logstash同步es因為是做esde查詢所以我單獨部署的es系統。跟下面要介紹的elk是獨立開來的,不涉及日誌操作就隔離開了。

 

首先在虛擬機器目錄下面新建了一個elk資料夾。在elk資料夾下面透過wget 和github的下載連結把包下載下來,解壓後就成了下面的樣子。後面主要做的就是執行docker-compose up -d。github下面有詳細介紹這個執行的命令和操作。這裡需要踩坑就是docker和docker-compose的版本最好是最新的,太老的話執行docker-compose up -d會報一堆錯誤。

開啟github下docker-elk的源地址

deviantony/docker-elk: The Elastic stack (ELK) powered by Docker and Compose. (github.com)

 

透過檢視docker-compose.yml可以看到它的配置,裝完後他會預設開啟以下這些埠

5000: Logstash TCP input(Logstash資料的接收通道)
9200: Elasticsearch HTTP(ES的http通道)
9300: Elasticsearch TCP transport(ES的TCP通道)
5601: Kibana(UI管理介面)

開啟ip:5601的古管理介面,這裡用到了es商業版本,會有預設的登陸賬號elastic、密碼changeme 。我這裡有測試過所以有產生幾條資料。

 

下面新建net7的專案,新建配置檔案Nlog.config

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogLevel="Warn"
      internalLogFile="internal-nlog.txt">

  <extensions>
    <add  assembly="NLog.Web.AspNetCore"/>
  </extensions >
  <variable name="logDirectory" value="${basedir}\logs\"/>
  <!--define various log targets-->
  <targets>
    <!--write logs to file-->
    <!--address 填寫Logstash資料的接收通道-->
    <target xsi:type="Network"
            name="elastic"
            keepConnection="false"
            address ="tcp://my.es.com:50000"
            layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" />
    />
    <target xsi:type="Null" name="blackhole" />
  </targets>
  <rules>
    <!--All logs, including from Microsoft-->
    <!--<logger name="*" minlevel="Trace" writeTo="allfile" />-->
    <!--Skip Microsoft logs and so log only own logs-->
    <logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" />
    <logger name="*" minlevel="Trace" writeTo="elastic" />
  </rules>
</nlog>

這裡i只需要配置logstash接受資料通道50000,加上Program一行程式碼,當然NLog.Extensions.Logging 、NLog.Web.AspNetCore連個nuget包是需要引用的。

只是測試一下是否可用,所以測試程式碼就這麼一點。

下面就可以執行專案呼叫swagger的介面了。上面有配置txt輸出 internalLogFile="internal-nlog.txt,會在專案中生成該檔案,透過該檔案可以檢視是否連結logstash成功,以及寫入。

生產專案中用的serilog寫入到logstash,使用中很方便。

logstash對於日誌量大的儲存一個月兩個月的日誌,效能也很不錯,問題排查也的很友好,特別是生產環境。

NLog不支援ILogger泛型和微軟自帶的相容好像沒有serilog那麼完美。當然沒怎麼使用和研究,NLog也有可能是我還沒學會怎麼用。

相關文章