저널: 허용되는 저널 크기를 채우는 서비스는 무엇입니까?

저널: 허용되는 저널 크기를 채우는 서비스는 무엇입니까?

Debian 시스템에서는 systemd-journal기본적으로 로그가 처리됩니다.

해당 구성은 사용할 수 있는 최대 디스크 공간을 제한합니다.

$ cat /etc/systemd/journald.conf
SystemMaxUse=100M
SystemKeepFree=200M

이제 해당 디렉토리는 약 1억 개로 가득 찼습니다.

$ du -hs /var/log/journal
109M    /var/log/journal

내부에 -잡지디렉터리에는 많은 바이너리 파일이 포함된 디렉터리가 하나만 있습니다.

이 109M 공간이 서비스별로 어떻게 할당되는지 알 수 있는 방법이 있나요?

nginx: 15M
httpd: 20M
...

현재로서는 이 정보를 확인할 수 있는 방법을 찾지 못했습니다.

답변1

이를 수행할 수 있지만 C API를 사용하여 로그의 모든 항목을 수동으로 검색해야만 합니다 sd-journal. 복잡하지 않습니다. 예제를 함께 복사하면 됩니다. 그 중 일부는 단편적인 부분에서 나옵니다.sd_journal_next맨페이지_get_data다음으로 바꾸십시오 _enumerate_data:

소스코드 올려드릴께요여기. **이것은 약간 빠르고 지저분하며 sd_*문서가 실제로 그다지 좋지 않으므로 상황이 정확하기를 바랍니다.

/* SPDX-License-Identifier: GPLv3 */
/* Copyright 2023 Marcus Müller
 * Somewhat based on man sd_journal_get_data (MIT-0), but most of the original work by
 * Marcus Müller
 */

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <systemd/sd-journal.h>

const char* KEY = "_SYSTEMD_UNIT=";
const char* ALTKEY = "_TRANSPORT=";
int main(int argc, char* argv[])
{
    int r;
    size_t KEYLEN = strlen(KEY);
    size_t ALTKEYLEN = strlen(ALTKEY);
    sd_journal* j;
    r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
    if (r < 0) {
        errno = -r;
        fprintf(stderr, "Failed to open journal: %m\n");
        return 1;
    }
    /* Print header */
    puts("unit name;length\n");

    SD_JOURNAL_FOREACH(j)
    {
        const char* data_ptr;
        size_t field_length;
        size_t total_length = 0;
        char* unitname = NULL;
        size_t unitname_len = 0;
        int unit_found = 0;

        while (0 < sd_journal_enumerate_data(j, (const void**)&data_ptr, &field_length)) {
            /* We just break the counting if we encounter a broken entry. */
            total_length += field_length;
            if (unit_found == 0) {
                if (field_length > KEYLEN && strncmp(data_ptr, KEY, KEYLEN) == 0) {
                    unit_found = 1;
                    unitname_len = field_length - KEYLEN;
                    unitname = realloc(unitname, unitname_len);
                    strncpy(unitname, data_ptr + KEYLEN, unitname_len);
                } else if (field_length > ALTKEYLEN && (unitname_len == 0) &&
                           strncmp(data_ptr, ALTKEY, ALTKEYLEN) == 0) {
                    unitname_len = field_length - ALTKEYLEN;
                    unitname = realloc(unitname, unitname_len);
                    strncpy(unitname, data_ptr + ALTKEYLEN, unitname_len);
                }
            }
        }

        if (unitname_len == 0) {
            printf("UNKNOWN;%zu\n", total_length);
        } else {
            printf("%*s;%zu\n", (int)unitname_len, unitname, total_length);
            free(unitname);
        }
    }
    sd_journal_close(j);
    return 0;
}

다른 이름으로 저장 journalsizes.c, 다음으로 컴파일

c99 -o journalsizes $(pkg-config --cflags --libs libsystemd) journalsizes.c

./journalsizes세미콜론으로 구분된 단위 이름 목록(바이트 단위)을 얻으 려면 실행하세요 .

예를 들어, 다음과 같은 텍스트 파일에 넣어서 사용할 수 있습니다.누적 로그 크기.sql다음과 같은:

.mode csv
.separator ;
.import "|./journalsizes" journal
SELECT
  "unit name",
  SUM("length")/(1024*1024.0) AS megabyte
FROM
  journal
GROUP BY
  "unit name"
ORDER BY
  megabyte
DESC LIMIT 10;

다음을 통해 실행하십시오 sqlite3.

sqlite3 < accumulate_logsizes.sql

관련 정보