閱讀589 返回首頁    go 微信


syslog__loghub-采集_用戶指南_日誌服務-阿裏雲

logtail目前支持的接入端主要有syslog和文本文件,如下圖所示:

本文將重點介紹怎麼將syslog數據打通logtail,進而收集到LogHub。

  • syslog是什麼?

可以參考鳥哥的Linux私房菜

  • 和利用文本文件相比,使用syslog有哪些優勢?

不落盤、保密性好。免去了文件落盤和解析的代價,單機可達80MB/S吞吐率

logtail支持在本地配置tcp端口,接收syslog agent轉發過來的日誌,logtail、syslog、loghub三者之間的關係如下圖所示,logtail開啟tcp端口,接收rsyslog或者其他syslog agent通過tcp協議轉發過來的syslog數據,logtail解析接收到的數據並轉發到loghub中。

如果要使用該功能,請按照以下步驟操作:

step 1: 控製台創建syslog相關配置

控製台創建logtail syslog配置,配置中需要填寫tag域,並將syslog log配置應用到machine group上,假設這一步配置的tag是sys_tag。

step 2: 配置Logtail使得協議生效

從機器logtail安裝目錄下找到ilogtail_config.json,一般在目錄/usr/local/ilogtail/下麵,根據需求修改和syslog相關的配置,修改完之後使用重啟logtail。重啟logtail要先stop掉再start。

  1. sudo /etc/init.d/ilogtaild stop
  2. sudo /etc/init.d/ilogtaild start
  1. # 是否打開syslog功能,false表示關閉,true表示打開。
  2. "streamlog_open" : true,
  3. # syslog用於接收日誌的內存池大小,程序啟動時會一次性申請這麼大的內存,請根據機器內存大小以及實際需求填寫,單位是MB。
  4. "streamlog_pool_size_in_mb" : 50,
  5. # logtail每次調用socket io rcv接口使用的緩衝區大小,單位是byte。
  6. "streamlog_rcv_size_each_call" : 1024,
  7. # 定義syslog的日誌格式,具體含義下麵會解釋。
  8. "streamlog_formats":[],
  9. # logtail用於接收syslog日誌的tcp端口,默認是11111
  10. "streamlog_tcp_port" : 11111

step 3: 安裝rsyslog,並修改配置

如果機器已經安裝rsyslog,忽略這一步。

在/etc/rsyslog.conf中根據需要修改配置,下麵給一個例子:

  1. $WorkDirectory /var/spool/rsyslog # where to place spool files
  2. $ActionQueueFileName fwdRule1 # unique name prefix for spool files
  3. $ActionQueueMaxDiskSpace 1g # 1gb space limit (use as much as possible)
  4. $ActionQueueSaveOnShutdown on # save messages to disk on shutdown
  5. $ActionQueueType LinkedList # run asynchronously
  6. $ActionResumeRetryCount -1 # infinite retries if host is down
  7. # 定義日誌數據的字段
  8. $template ALI_LOG_FMT,"0.1 sys_tag %timegenerated:::date-unixtimestamp% %fromhost-ip% %hostname% %pri-text% %protocol-version% %app-name% %procid% %msgid% %msg:::drop-last-lf%n"
  9. *.* @@10.101.166.173:11111;ALI_LOG_FMT

注意模板ALI_LOG_FMT中第二個域的值是sys_tag,這個取值必須和step 1中創建的一致,這個配置的含義是將本機接收到的所有(*.*)syslog日誌按照ALI_LOG_FMT格式化,使用tcp協議轉發到10.101.166.173:11111。機器10.101.166.173必須在step 1中的machine group中並且按照step 2配置好。

接著啟動rsyslog(sudo /etc/init.d/rsyslog restart),啟動之前請先檢查機器上是否安裝了其他syslog的agent,比如syslogd、sysklogd、syslog-ng等,如果有的話請stop掉。

上麵三步走完之後就可以將機器上的syslog收集到日誌服務了,下麵將討論格式化syslog日誌的方式以及收集的原理,如果不需要格式化syslog數據,可以忽略。

基本原理

logtail通過tcp端口接收到的數據是流式的,如果要從流式的數據中解析出一條條的日誌,日誌格式必須滿足一些要求:

  • 每條日誌之間使用換行符(n)分隔,一條日誌內部不可以出現換行符。
  • 日誌內部除了消息正文可以包含空格,其他字段不可以包含空格。

定義日誌格式如下:

  1. $version $tag $unixtimestamp $ip [$user-defined-field-1 $user-defined-field-2 $user-defined-field-n] $msgn"

各個字段含義為:

  • version: 該日誌格式的版本號,logtail使用該版本號解析user-defined-field字段,具體解析方法後麵會解釋。
  • tag: 數據標簽,用於尋找project/logstore,和上麵step 1中的tag含義相同,不可以包含空格和換行符。
  • unixtimestamp: 該條日誌的時間戳。
  • ip: 該條日誌的對應的機器ip,如果日誌中的該字段是127.0.0.1,最終發往服務端的日誌數據中該字段會被替換成tcp socket的對端地址。
  • user-defined-field: 用戶自定義字段,中括號表示是可選字段,可以有0個或多個,不可以包含空格和換行符。
  • msg: 日誌消息正文,不可以包含換行符,末尾的n表示換行符。

舉個例子,下麵的日誌便是滿足上麵格式要求的日誌:

  1. 2.1 streamlog_tag 1455776661 10.101.166.127 ERROR com.alibaba.streamlog.App.main(App.java:17) connection refused, retry

原理講到這裏大家就會發現不僅syslog日誌可以接入logtail,任何日誌工具隻要能滿足下麵兩點要求,都可以接入:

  • 可以將日誌格式化,格式化之後的日誌格式滿足上麵的要求。
  • 可以通過tcp協議將日誌append到遠端。

logtail為了解析上述日誌格式,需要增加一些配置,舉例如下:

  1. "streamlog_formats":
  2. [
  3. {"version": "2.1", "fields": ["level", "method"]},
  4. {"version": "2.2", "fields": []},
  5. {"version": "2.3", "fields": ["pri-text", "app-name", "syslogtag"]}
  6. ]

logtail通過讀取到的version字段到streamlog_formats中找到對應的user-defined字段的格式,應用該配置,上麵的日誌樣例version字段為2.1,包含兩個自定義字段level和method,因此日誌樣例將被解析成如下格式:

  1. {
  2. "source": "10.101.166.127",
  3. "time": 1455776661,
  4. "level": "ERROR",
  5. "method": "com.alibaba.streamlog.App.main(App.java:17)",
  6. "msg": "connection refused, retry"
  7. }

到這裏version和tag字段的作用就解釋完了,簡單概括就是version用於正確的解析user-defined字段,tag用於尋找數據將要被發送到的project/logstore,這兩個字段不會作為日誌內容發送到阿裏雲日誌服務, 另外,logtail預定義了一些日誌格式,這些內置的格式都使用0.1、1.1這樣以”0.”、”1.”開頭的version值,所以用戶自定義version不可以以”0.”、”1.”開頭。

常見日誌工具接入logtail syslog log

log4j

  • 引入log4j 庫.

    1. <dependency>
    2. <groupId>org.apache.logging.log4j</groupId>
    3. <artifactId>log4j-api</artifactId>
    4. <version>2.5</version>
    5. </dependency>
    6. <dependency>
    7. <groupId>org.apache.logging.log4j</groupId>
    8. <artifactId>log4j-core</artifactId>
    9. <version>2.5</version>
    10. </dependency>
  • 程序中引入log4j配置文件log4j_aliyun.xml:
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <configuration status="OFF">
    3. <appenders>
    4. <Socket name="StreamLog" protocol="TCP" host="10.101.166.173" port="11111">
    5. <PatternLayout pattern="%X{version} %X{tag} %d{UNIX} %X{ip} %-5p %l %enc{%m}%n" />
    6. </Socket>
    7. </appenders>
    8. <loggers>
    9. <root level="trace">
    10. <appender-ref ref="StreamLog" />
    11. </root>
    12. </loggers>
    13. </configuration>
    其中10.101.166.173:11111是logtail所在機器的地址。
  • 程序中設置ThreadContext。

    1. package com.alibaba.streamlog;
    2. import org.apache.logging.log4j.LogManager;
    3. import org.apache.logging.log4j.Logger;
    4. import org.apache.logging.log4j.ThreadContext;
    5. public class App
    6. {
    7. private static Logger logger = LogManager.getLogger(App.class);
    8. public static void main( String[] args ) throws InterruptedException
    9. {
    10. ThreadContext.put("version", "2.1");
    11. ThreadContext.put("tag", "streamlog_tag");
    12. ThreadContext.put("ip", "127.0.0.1");
    13. while(true)
    14. {
    15. logger.error("hello world");
    16. Thread.sleep(1000);
    17. }
    18. //ThreadContext.clearAll();
    19. }
    20. }

tengine

tengine 可以通過syslog接入ilogtail.

tengine使用ngx_http_log_module模塊將日誌打入本地syslog agent,在本地syslog agent中forward到rsyslog。

tengine配置syslog請參考:https://tengine.taobao.org/document_cn/http_log_cn.html

example:

以user類型和info級別將access log發送給本機Unix dgram(/dev/log),並設置應用標記為nginx

  1. access_log syslog:user:info:/var/log/nginx.sock:nginx

rsyslog 配置:

  1. module(load="imuxsock") # needs to be done just once
  2. input(type="imuxsock" Socket="/var/log/nginx.sock" CreatePath="on")
  3. $template ALI_LOG_FMT,"2.3 streamlog_tag %timegenerated:::date-unixtimestamp% %fromhost-ip% %pri-text% %app-name% %syslogtag% %msg:::drop-last-lf%n"
  4. if $syslogtag == 'nginx' then @@10.101.166.173:11111;ALI_LOG_FMT

nginx

以收集nginx accesslog為例。

access log配置

  1. access_log syslog:server=unix:/var/log/nginx.sock,nohostname,tag=nginx;

rsyslog 配置:

  1. module(load="imuxsock") # needs to be done just once
  2. input(type="imuxsock" Socket="/var/log/nginx.sock" CreatePath="on")
  3. $template ALI_LOG_FMT,"2.3 streamlog_tag %timegenerated:::date-unixtimestamp% %fromhost-ip% %pri-text% %app-name% %syslogtag% %msg:::drop-last-lf%n"
  4. if $syslogtag == 'nginx' then @@10.101.166.173:11111;ALI_LOG_FMT

參考:https://nginx.org/en/docs/syslog.html

Python Syslog

example:

  1. import logging
  2. import logging.handlers
  3. logger = logging.getLogger('myLogger')
  4. logger.setLevel(logging.INFO)
  5. #add handler to the logger using unix domain socket '/dev/log'
  6. handler = logging.handlers.SysLogHandler('/dev/log')
  7. #add formatter to the handler
  8. formatter = logging.Formatter('Python: { "loggerName":"%(name)s", "asciTime":"%(asctime)s", "pathName":"%(pathname)s", "logRecordCreationTime":"%(created)f", "functionName":"%(funcName)s", "levelNo":"%(levelno)s", "lineNo":"%(lineno)d", "time":"%(msecs)d", "levelName":"%(levelname)s", "message":"%(message)s"}')
  9. handler.formatter = formatter
  10. logger.addHandler(handler)
  11. logger.info("Test Message")

最後更新:2016-11-23 17:16:10

  上一篇:go producer-lib__loghub-采集_用戶指南_日誌服務-阿裏雲
  下一篇:go unity3d__loghub-采集_用戶指南_日誌服務-阿裏雲