#6 Loki 日志系统

2021-12-05

Loki

Grafana 公司出品的一个日志系统。才出来没两年,是一个相对较年轻的项目,不过已经有一定知名度了。

业界最为知名的日志系统是 ELK,它对日志做全文索引,搜索起来最快、最灵活,同时大量索引导致存储成本相对较高。
Loki 则将日志分成时间戳、标签、正文三部分,标签就是索引,存储在

Promtail

Grafana

Grafana 是一个数据面板,常用于监控系统。它本身不会收集和存储数据,而是通过接入其他数据源来实现。

通过内置的插件,Loki 可以支持各种关系型数据库和时序数据库(Zabbix 一般配套使用 MySQL 做存储,Prometheus 本身就可以认为是一个时序数据库),也支持 Loki,Elasticsearch 这样的数据源。

实验

Install Loki & Promtail

# 获取最新版本号
# LOKI_VERSION=$(curl -s https://api.github.com/repos/grafana/loki/releases/latest | jq -r .tag_name)
LOKI_VERSION=$(curl -s https://api.github.com/repos/grafana/loki/releases/latest | grep -Po '"tag_name": "\Kv[0-9.]+')

# 下载 loki & promtail
curl -O -L "https://github.com/grafana/loki/releases/download/${LOKI_VERSION}/loki-linux-amd64.zip"
curl -O -L "https://github.com/grafana/loki/releases/download/${LOKI_VERSION}/promtail-linux-amd64.zip"
# loki    : 18M -> 57M
# promtail: 21M -> 74M

# 解压 & 设置
unzip loki-linux-amd64.zip promtail-linux-amd64.zip
sudo mv -n loki-linux-amd64 /usr/local/bin/loki
sudo mv -n promtail-linux-amd64 /usr/local/bin/promtail
# chmod a+x /usr/local/bin/{loki,promtail} # already 755

# 下载配置文件
sudo -E wget -qO /etc/loki.config.yaml "https://raw.githubusercontent.com/grafana/loki/${LOKI_VERSION}/cmd/loki/loki-local-config.yaml"
sudo -E wget -qO /etc/promtail.config.yaml "https://raw.githubusercontent.com/grafana/loki/${LOKI_VERSION}/clients/cmd/promtail/promtail-local-config.yaml"
ls -l /etc/{loki,promtail}.config.yaml

# 启动 loki
loki -config.file /etc/loki.config.yaml
# 在另一个终端查看
browse http://localhost:3100/metrics

# 启动 promtail

Install Grafana

Install on Debian or Ubuntu

sudo apt-get install -y apt-transport-https software-properties-common wget
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -

echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
# Bate 版本
# echo "deb https://packages.grafana.com/oss/deb beta main" | sudo tee -a /etc/apt/sources.list.d/grafana.list

sudo apt-get update
sudo apt-get install -y grafana
# 无法创建主目录"/usr/share/grafana"

# sudo systemctl daemon-reload
# sudo systemctl enable grafana-server
sudo systemctl start grafana-server

browse http://localhost:3000

参考资料与拓展阅读

#4 Graylog Search 规则

2021-01-06
ssh         // 包含 ssh
ssh login   // 包含 ssh 或者 login
"ssh login" // 包含 ssh login

// 正则匹配
/ethernet[0-9]+/

type:(ssh OR login) // 字段 type 包含 ssh 或者 login

// 必须 (不) 包含字段
_exists_:type
NOT _exists_:type

// 支持 `*`, `?` 两种通配符
source:xxx?yyy
source:xxx*yyy
// PS: 默认配置,通配符不能放在最前面,避免内存消耗太多
// 可以这样开启:
// allow_leading_wildcard_searches = true

// 模糊匹配 ~
ssh logni~      // 可以搜索到 ssh login
"foo bar"~5     //  Damerau–Levenshtein distance

// 范围
http_response_code:[500 TO 504]
http_response_code:{400 TO 404}
bytes:{0 TO 64]
http_response_code:[0 TO 64}

// 大小
http_response_code:>400
http_response_code:<400
http_response_code:>=400
http_response_code:<=400
http_response_code:(>=400 AND <500)

// 时间范围
timestamp:["2019-07-23 09:53:08.175" TO "2019-07-23 09:53:08.575"]
otherDate:[now-5d TO now-4d]

此外,还有 AND,OR,NOT,括号等逻辑运算符可用。

转义符:

& | : \ / + - ! ( ) { } [ ] ^ " ~ * ?

参考资料与拓展阅读

#3 logging 增加 TRACE 级别日志

2020-05-21

logging 内部的服务级别:

DEBUG       10
INFO        20
WARNING     30
ERROR       40
CRITICAL    50

根据使用习惯,INFO 是重要信息,DEBUG 是普通信息。线上也是开到 DEBUG 级别。
然后调试信息也是通过 DEBUG 服务打印,然后通过 conf.DEBUG_MODE 来区分是不是要打印这种 DEBUG 级别的调试信息。

觉得不甚方便,想了一下,有两种思路:

  1. 将普通信息也通过 INFO 日志打印,在日志内容中插入部分标识来表示是重要信息,比如 “&NOTICE”。
  2. 增加一个 TRACE 级别日志。

方案一感觉相对合理一些,但是对于已有项目还是方案二好。

实现

def trace(self, message, *args, **kwargs):
    if self.isEnabledFor(TRACE):
        self._log(TRACE, message, args, **kwargs)


TRACE = logging.TRACE = 5
logging.addLevelName(TRACE, 'TRACE')
logging.Logger.trace = trace

参考:syslog 日志级别

  • EMERG:系统不可用
  • ALERT:需要立即采取行动
  • CRIT:关键错误
  • ERR:一般错误
  • WARNING:警告
  • NOTICE:一般通知
  • INFO:信息性消息
  • DEBUG:调试级别的消息

参考:nodejs winston 日志级别

  • error:错误
  • warn:警告
  • info:一般信息
  • http:HTTP 请求
  • verbose:详细信息
  • debug:调试信息
  • silly:非常详细的调试信息

参考:java log4j 日志级别

  • FATAL:致命
  • ERROR:错误
  • WARN:警告
  • INFO:信息
  • DEBUG:调试
  • TRACE:跟踪

#2 Logrotate

2018-05-03

配置

# cat /etc/logrotate.conf
weekly
su root adm
rotate 4
create
#dateext
#compress
include /etc/logrotate.d

以 Nginx 配置为例:

# cat /etc/logrotate.d/nginx
/var/log/nginx/*.log {
        daily       # 按日切割
        missingok   # 如果文件不存在,则不创建
        rotate 14   # 最多保留 14 个日志文件
        compress    # 压缩
        delaycompress   # 延迟压缩
        notifempty      # 如果文件为空,则不创建
        create 0640 www-data adm

        # 可能一次切割多个日志,
        # 但是后面遇到的每个脚本都只执行一次,
        # 在所有日志切割之前或之后
        sharedscripts

        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi \
        endscript

        postrotate
                invoke-rc.d nginx rotate >/dev/null 2>&1
        endscript
}

其他常用选项:

  • dateext 部分日志需要添加日期后缀
  • lastaction/endscript 最后执行的指令,很有用,比如最后将日志备份到某些地方

比如:

rsync -au *.gz 192.168.64.234:/backup/nginx-logs/`hostname -s`/

参考资料与拓展阅读