关于Journal Log

简介

Journal是systemd 为自己提供的日志系统。使用systemd日志,无须额外提供日志服务(syslog)。读取日志的命令:

# journalctl

默认情况下(当 Storage= 在文件 /etc/systemd/journald.conf 中被设置为 auto),日志记录将被写入 /var/log/journal/。该目录是 systemd 软件包的一部分。若被删除,systemd 不会自动创建它,直到下次升级软件包时重建该目录。如果该目录缺失,systemd 会将日志记录写入 /run/systemd/journal。这意味着,系统重启后日志将丢失

提示: 如果 /var/log/journal/ 位于 btrfs 文件系统,应该考虑对这个目录禁用写入时复制,方法参阅Btrfs#Copy-on-Write (CoW)

Systemd 日志事件提示信息的记录按照优先级功能进行分离,符合经典的 BSD syslog 协议风格([Syslog],RFC 5424)。

输出过滤

journalctl 可以根据特定字段过滤输出。

日志大小限制

如果按上面的操作保留日志的话,默认日志最大限制为所在文件系统容量的 10%,即:如果 /var/log/journal 储存在 50GiB 的根分区中,那么日志最多存储 5GiB 数据。可以修改配置文件指定最大限制。如限制日志最大 50MiB:

/etc/systemd/journald.conf

 SystemMaxUse=50M

还可以通过配置片段而不是全局配置文件进行设置:

/etc/systemd/journald.conf.d/00-journal-size.conf

[Journal]
SystemMaxUse=50M

修改配置后要立即生效,需重启 systemd-journald.service 服务。

详情参见 journald.conf(5).

Journal log 日志流

日志输入
  • 通过kmsg,获取内核日志
    systemd-journald 会监听 socket dev/kmsg 来获取 kernel log messages.
    journald-kmsg.c

    int server_open_dev_kmsg(Server *s) {
        ...
        s->dev_kmsg_fd = open("/dev/kmsg", mode);
        ...
    }
    
  • 通过syslog(3) 调用,获取简单系统日志。
    src/core/namespace.c

    static int mount_private_dev(MountEntry *m) {
        ...
        devlog = strjoina(temporary_mount, "/dev/log");
        if (symlink("/run/systemd/journal/dev-log", devlog) < 0)
        ...
    }
    

    journald-server.c

    int server_init(Server *s, const char *namespace) {
        ...
        /* systemd-journald-dev-log.socket: /run/systemd/journal/dev-log */
        r = server_open_syslog_socket(s, syslog_socket);
        ...
    }
    

    Journal log 兼容syslog, 即通过syslog(3) 打印的log 也会存储到 Journal log 中.
    systemd-journald 通过监听 socket /run/systemd/journal/dev-log 获取到 syslog(3). 因为通常在装有systemd的系统中 /dev/log/run/systemd/journal/dev-log 的一个软连接,而syslog(3)会将log 发送到/dev/log

  • 通过原生Journal API sd_journal_print(4),获取结构化系统日志
    journal-send.c

    _public_ int sd_journal_send(const char *format, ...) {
        ...
        r = sd_journal_sendv(iov, i);
        ...
    }
    
    _public_ int sd_journal_sendv(const struct iovec *iov, int n) {
        ...
        static const union sockaddr_union sa = {
                .un.sun_family = AF_UNIX,
                .un.sun_path = "/run/systemd/journal/socket",
        };
        ...
    }
    
    _public_ int sd_journal_printv(int priority, const char *format, va_list ap) {
        ...
        return sd_journal_sendv(iov, 2);
        ...
    }
    
  • 通过标准输出以及错误输出,获取systemd service 日志。
    journal-send.c

    _public_ int sd_journal_send(const char *format, ...) {
        ...
        r = sd_journal_sendv(iov, i);
        ...
    }
    
    _public_ int sd_journal_sendv(const struct iovec *iov, int n) {
        ...
        static const union sockaddr_union sa = {
                .un.sun_family = AF_UNIX,
                .un.sun_path = "/run/systemd/journal/socket",
        };
        ...
    }
    
    _public_ int sd_journal_printv(int priority, const char *format, va_list ap) {
        ...
        return sd_journal_sendv(iov, 2);
        ...
    }
    

    systemd service 可以通过设置 StandardOutput=journal/ StandardError=journal 将标准输出和错误输出存储到Journal log 中.
    systemd-journald 通过监听 socket /run/systemd/journal/stdout 获取service的log(以systemd 启动的service, fd stdout/stderr (1/2) 会被重定向到/run/systemd/journal/stdout)。

  • 通过内核audit 子系统,获取Audit log
    journald-audit.c

    int server_open_audit(Server *s) {
        ...
        s->audit_fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_AUDIT);
        ...
    }           
    
日志输出

systemd 提供了 socket /run/systemd/journal/syslog,以兼容传统日志服务。所有系统信息都会被传入。要使传统日志服务工作,需要让服务链接该 socket,而非 /dev/log官方说明)。

journald.conf 使用 no 转发socket . 为了使 syslog-ng 配合 journald , 你需要在 /etc/systemd/journald.conf 中设置 ForwardToSyslog=yes . 参阅 Syslog-ng#Overview 了解更多细节.
journald-syslog.c

static void forward_syslog_iovec(
    ...
    j = strjoina(s->runtime_directory, "/syslog");
    ...
}

如果选择使用 rsyslog , 因为 rsyslog 从日志中 直接 读取Log (sd_journal_open/sd_journal_get_data),所以不再需要改变那个选项.

rsyslog/plugins/imjournal/imjournal.c

static rsRetVal openJournal(void) {
    ...
    if ((r = sd_journal_open(&journalContext.j, cs.bRemote? 0 : SD_JOURNAL_LOCAL_ONLY)) < 0) {
        LogError(-r, RS_RET_IO_ERROR, "imjournal: sd_journal_open() failed");
        iRet = RS_RET_IO_ERROR;
    }
    ...
}

static int journalGetData(const char *field, const void **data, size_t *length)
{
    ...
    ret = sd_journal_get_data(journalContext.j, field, data, length);
    ...
}
相关 socket
socket 说明
/run/systemd/journal/dev-log 用以监听syslog(3)的输出
/run/systemd/journal/stdout 用以监听systemd service 的标准/错误输出
/run/systemd/journal/socket 用以监听jurnal原始打印API日志输入
/run/systemd/journal/syslog 如果存在,systemd-journal 将收到的log 转发到该socket。但由于rsyslog更喜欢从日志中提取信息,而不是通过套接字接收消息,所以该socket一般不启用。
流程图
systemd-journal 日志流

参考文章

systemd/Journal (简体中文)
systemd-journald.socket (8) - Linux Man Pages

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容