全部产品
存储与CDN 数据库 安全 应用服务 数加·人工智能 数加·大数据基础服务 互联网中间件 视频服务 开发者工具 解决方案 物联网
日志服务

syslog收集参考

更新时间:2017-10-26 15:02:47

Logtail目前支持的接入端为syslog和文本文件,如下图所示:

Logtail通过TCP协议支持syslog。配置Logtail采集syslog日志详细步骤请参见通过Logtail采集syslog日志

syslog优势

syslog概念请参考 鸟哥的 Linux 私房菜

和利用文本文件相比,使用syslog时日志数据直接收集到LogHub,不会保存到磁盘,保密性好。免去了文件缓存和解析的代价,单机可达80MB/s吞吐率。

基本原理

Logtail 支持在本地配置TCP端口,接收syslog Agent转发的日志。Logtail开启TCP端口,接收rsyslog或者其他syslog Agent通过TCP协议转发过来的syslog数据,Logtail解析接收到的数据并转发到LogHub中。配置Logtail采集syslog日志过程请参见通过Logtail采集syslog日志。Logtail、syslog、LogHub三者之间的关系如下图所示。

syslog日志格式

Logtail通过TCP端口接收到的数据是流式的,如果要从流式的数据中解析出一条条的日志,日志格式必须满足以下条件:

  • 每条日志之间使用换行符(\n)分隔,一条日志内部不可以出现换行符。
  • 日志内部消息正文可以包含空格,其他字段不可以包含空格。

syslog日志格式如下:

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

各个字段含义:

日志字段 含义
version 该日志格式的版本号,Logtail使用该版本号解析user-defined-field 字段。
tag 数据标签,用于寻找Project或Logstore,不可以包含空格和换行符。
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解析syslog日志规则

Logtail 需要增加配置以解析syslog日志。例如:

  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用于解析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请参考:tengine配置syslog

示例:

以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

参考:nginx

Python Syslog

示例:

  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")
本文导读目录