서비스 상태가 변경될 때 스크립트를 실행하는 방법이 있습니까?

서비스 상태가 변경될 때 스크립트를 실행하는 방법이 있습니까?

중요한 서비스가 중지되면 스크립트를 실행하여 나에게 알리거나 미리 정의된 작업을 수행하여 서비스를 복원할 수 있도록 실행 중인 서비스의 상태에 연결하고 싶습니다.

답변1

아니요어느제공하다. systemd 관리자의 dbus 인터페이스는 이러한 유형의 전역 알림을 제공하지 않습니다. 전역적으로 트리거되는 신호를 찾고 있다면 관리자의 신호는 성능상의 이유로 약간 제한됩니다.

$ busctl introspect org.freedesktop.systemd1 \
    /org/freedesktop/systemd1 \
    org.freedesktop.systemd1.Manager \
    | grep signal
.JobNew                                   signal    uos              -                -
.JobRemoved                               signal    uoss             -                -
.Reloading                                signal    b                -                -
.StartupFinished                          signal    tttttt           -                -
.UnitFilesChanged                         signal    -                -                -
.UnitNew                                  signal    so               -                -
.UnitRemoved                              signal    so               -                -

전체 인터페이스는 여기에서 볼 수 있습니다:

https://www.freedesktop.org/software/systemd/man/org.freedesktop.systemd1.html

그러나 특정 서비스의 상태가 변경되었는지 알고 싶다면 해당 특정 서비스에 가입하면 됩니다. 예: sshd.service:

$ busctl introspect \
    org.freedesktop.systemd1 \
    /org/freedesktop/systemd1/unit/sshd_2eservice \
    org.freedesktop.DBus.Properties 
NAME                            TYPE      SIGNATURE RESULT/VALUE FLAGS
.Get                            method    ss        v            -
.GetAll                         method    s         a{sv}        -
.Set                            method    ssv       -            -
.PropertiesChanged              signal    sa{sv}as  -            -

.PropertiesChanged속성이 변경될 때마다 신호가 발생합니다.

관심을 가질 수 있는 속성은 또는 인터페이스에 있습니다 .ActiveState..SubStateorg.freedesktop.systemd1.Unit

$ busctl introspect \
    org.freedesktop.systemd1 \
    /org/freedesktop/systemd1/unit/sshd_2eservice \
    org.freedesktop.systemd1.Unit
...
.ActiveState    property  s         "active"         emits-change
.SubState       property  s         "running"        emits-change

그렇다면 어떻게 구독하고 이 데이터를 얻을 수 있을까요? 어떻게 스크립트를 작성해야 할지 모르겠지만 #include <systemd/sd-bus.h>sd-bus API()를 사용하여 C로 뭔가를 작성하겠습니다. 이를 위해서는 다음 단계가 필요합니다.

  • 개방형 버스:
int r = sd_bus_default_system(&m_bus);
  • 특정 단위의 변경 사항을 구독하세요.
    sd_bus_match_signal(
        m_bus,
        NULL, // slot
        NULL, // sender
        "/org/freedesktop/systemd1/unit/sshd_2eservice", // path
        "org.freedesktop.DBus.Properties", // interface
        "PropertiesChanged", // member
        callback, // callback
        NULL // userdata
    );

    sd_bus_match_signal(
        m_bus,
        NULL,
        NULL,
        "/org/freedesktop/systemd1/unit/network_2etarget",
        "org.freedesktop.DBus.Properties",
        "PropertiesChanged",
        callback,
        NULL
    );
  • 변경 사항에 반응하고 새로운 상태를 얻습니다.
int callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
{
    sd_bus_error err = SD_BUS_ERROR_NULL;
    char* msg = NULL;
    int r;

    r = sd_bus_get_property_string(m_bus,
        "org.freedesktop.systemd1",
        sd_bus_message_get_path(m), // (/org/freedesktop/systemd1/unit/sshd_2eservice)
        "org.freedesktop.systemd1.Unit",
        "ActiveState",
        &err,
        &msg);

    if (r < 0) { /* Error */ }

    sd_bus_error_free(&err);

    printf("Property change, state is: %s\n", msg);
    free (msg);
}

관련 답변은 다음과 같습니다. https://stackoverflow.com/questions/61940461/how-to-get-the-state-of-a-service-with-sd-bus/62038047#62038047

답변2

간단한 가능성은 로그 출력을 추적하는 것입니다 journalctl -f. 쉬운 구문 분석을 위해 json을 포함한 여러 출력 형식 옵션이 있습니다.

관련 정보