diff --git a/packages/journald/_dev/build/build.yml b/packages/journald/_dev/build/build.yml new file mode 100644 index 000000000000..a138b554aa08 --- /dev/null +++ b/packages/journald/_dev/build/build.yml @@ -0,0 +1,3 @@ +dependencies: + ecs: + reference: git@1.11 diff --git a/packages/journald/_dev/build/docs/README.md b/packages/journald/_dev/build/docs/README.md new file mode 100644 index 000000000000..64cd7270cf6c --- /dev/null +++ b/packages/journald/_dev/build/docs/README.md @@ -0,0 +1,8 @@ +# Journald Input + +The journald input integration reads logs from the `journald` system service. +The journald input reads the log data and the metadata associated with it. + +The journald input is available on Linux systems with `systemd` installed. + +{{fields "log"}} diff --git a/packages/journald/_dev/deploy/docker/docker-compose.yml b/packages/journald/_dev/deploy/docker/docker-compose.yml new file mode 100644 index 000000000000..a07f1a5d10f2 --- /dev/null +++ b/packages/journald/_dev/deploy/docker/docker-compose.yml @@ -0,0 +1,8 @@ +version: '2.3' +services: + journald: + image: alpine + volumes: + - ./sample_logs:/sample_logs:ro + - ${SERVICE_LOGS_DIR}:/var/log + command: /bin/sh -c "cp /sample_logs/* /var/log/" diff --git a/packages/journald/_dev/deploy/docker/sample_logs/test.journal b/packages/journald/_dev/deploy/docker/sample_logs/test.journal new file mode 100644 index 000000000000..c42b825e62dc Binary files /dev/null and b/packages/journald/_dev/deploy/docker/sample_logs/test.journal differ diff --git a/packages/journald/changelog.yml b/packages/journald/changelog.yml new file mode 100644 index 000000000000..d4c1729b4a67 --- /dev/null +++ b/packages/journald/changelog.yml @@ -0,0 +1,6 @@ +# newer versions go on top +- version: "0.0.1" + changes: + - description: Initial release of generic journald input package. + type: enhancement + link: https://github.com/elastic/integrations/pull/0 # FIXME Replace with the real PR link diff --git a/packages/journald/data_stream/log/_dev/test/system/test-journald-config.yml b/packages/journald/data_stream/log/_dev/test/system/test-journald-config.yml new file mode 100644 index 000000000000..a7b24e6615b4 --- /dev/null +++ b/packages/journald/data_stream/log/_dev/test/system/test-journald-config.yml @@ -0,0 +1,7 @@ +service: journald +input: journald +data_stream: + vars: + paths: + - "{{SERVICE_LOGS_DIR}}/test.journal" + tags: [forwarded] diff --git a/packages/journald/data_stream/log/agent/stream/journald.yml.hbs b/packages/journald/data_stream/log/agent/stream/journald.yml.hbs new file mode 100644 index 000000000000..9cc602ea857d --- /dev/null +++ b/packages/journald/data_stream/log/agent/stream/journald.yml.hbs @@ -0,0 +1,29 @@ +condition: ${host.platform} == 'linux' + +{{#if paths}} +paths: +{{#each paths as |path i|}} + - {{path}} +{{/each}} +{{/if}} + +{{#if include_matches}} +include_matches: +{{#each include_matches as |include_match i|}} + - '{{include_match}}' +{{/each}} +{{/if}} + +tags: +{{#each tags as |tag i|}} + - {{tag}} +{{/each}} + +{{#contains tags "forwarded"}} +publisher_pipeline.disable_host: true +{{/contains}} + +{{#if processors}} +processors: +{{processors}} +{{/if}} diff --git a/packages/journald/data_stream/log/elasticsearch/ingest_pipeline/default.yml b/packages/journald/data_stream/log/elasticsearch/ingest_pipeline/default.yml new file mode 100644 index 000000000000..07587b8c055e --- /dev/null +++ b/packages/journald/data_stream/log/elasticsearch/ingest_pipeline/default.yml @@ -0,0 +1,54 @@ +--- +description: Pipeline for processing journald logs. +processors: + - remove: + field: + - container.id_truncated # CONTAINER_ID from journald driver. + - log.syslog.facility.name # Duplicated as syslog.facility. + - syslog.priority # Duplicated as log.syslog.priority. + ignore_missing: true + + # Journald _CAP_EFFECTIVE. + # There is a typo in the field name from the input. + - rename: + field: journald.process.capabilites + target_field: journald.process.capabilities + ignore_missing: true + + # Journald CODE_FILE, CODE_LINE, CODE_FUNC. + - rename: + field: journald.code.file + target_field: log.origin.file.name + ignore_missing: true + - rename: + field: journald.code.line + target_field: log.origin.file.line + ignore_missing: true + - rename: + field: journald.code.func + target_field: log.origin.function + ignore_missing: true + + # Journald SYSLOG_FACILITY, SYSLOG_IDENTIFIER, SYSLOG_PID. + - rename: + field: syslog.pid + target_field: log.syslog.pid + ignore_missing: true + - rename: + field: syslog.identifier + target_field: log.syslog.identifier + ignore_missing: true + - rename: + field: syslog.facility + target_field: log.syslog.facility.code + ignore_missing: true + + # Cleanup an empty syslog object. + - remove: + if: ctx?.syslog != null && ctx.syslog instanceof Map && ctx.syslog.isEmpty() + field: syslog + +on_failure: +- set: + field: error.message + value: '{{ _ingest.on_failure_message }}' \ No newline at end of file diff --git a/packages/journald/data_stream/log/fields/agent.yml b/packages/journald/data_stream/log/fields/agent.yml new file mode 100644 index 000000000000..051c104fae2e --- /dev/null +++ b/packages/journald/data_stream/log/fields/agent.yml @@ -0,0 +1,2 @@ +- name: input.type + type: keyword diff --git a/packages/journald/data_stream/log/fields/base-fields.yml b/packages/journald/data_stream/log/fields/base-fields.yml new file mode 100644 index 000000000000..7c798f4534ca --- /dev/null +++ b/packages/journald/data_stream/log/fields/base-fields.yml @@ -0,0 +1,12 @@ +- name: data_stream.type + type: constant_keyword + description: Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: Data stream namespace. +- name: '@timestamp' + type: date + description: Event timestamp. diff --git a/packages/journald/data_stream/log/fields/ecs.yml b/packages/journald/data_stream/log/fields/ecs.yml new file mode 100644 index 000000000000..1b6dd97fbf95 --- /dev/null +++ b/packages/journald/data_stream/log/fields/ecs.yml @@ -0,0 +1,22 @@ +- name: ecs.version + external: ecs +- name: log.syslog.facility.code + external: ecs +- name: log.syslog.priority + external: ecs +- name: message + external: ecs +- name: process.args + external: ecs +- name: process.args_count + external: ecs +- name: process.command_line + external: ecs +- name: process.pid + external: ecs +- name: tags + external: ecs +- name: user.group.id + external: ecs +- name: user.id + external: ecs diff --git a/packages/journald/data_stream/log/fields/input.yml b/packages/journald/data_stream/log/fields/input.yml new file mode 100644 index 000000000000..99b92016644d --- /dev/null +++ b/packages/journald/data_stream/log/fields/input.yml @@ -0,0 +1,204 @@ +- name: container.log.tag + type: keyword + description: > + User defined tag of a container. Originates from the Docker journald logging driver. + +- name: container.partial + type: boolean + description: > + A field that flags log integrity when a message is split. The docker journald logging driver splits long message into multiple events. + +- name: host.hostname + type: keyword + description: > + The name of the originating host (from journald). + +- name: host.id + type: keyword + description: > + The machine ID of the originating host (from `machine-id`). + +- name: journald.audit.login_uid + type: long + description: > + The login UID of the process the journal entry originates from, as maintained by the kernel audit subsystem. + +- name: journald.audit.session + type: keyword + description: > + The session of the process the journal entry originates from, as maintained by the kernel audit subsystem. + +- name: journald.code.file + type: keyword + description: > + The code location generating this message, if known. Contains the source filename. + +- name: journald.code.func + type: keyword + description: > + The code location generating this message, if known. Contains the function name. + +- name: journald.code.line + type: long + description: > + The code location generating this message, if known. Contains the line number. + +- name: journald.coredump.unit + type: keyword + description: > + Used to annotate messages containing coredumps from system units. + +- name: journald.coredump.user_unit + type: keyword + description: > + Used to annotate messages containing coredumps from user units. + +- name: journald.gid + type: long + description: > + The group ID of the process the journal entry originates from formatted as a decimal string. Note that entries obtained via "stdout" or "stderr" of forked processes will contain credentials valid for a parent process. + +- name: journald.host.boot_id + type: keyword + description: > + The kernel boot ID for the boot the message was generated in, formatted as a 128-bit hexadecimal string. + +- name: journald.kernel.device + type: keyword + description: > + The kernel device name. If the entry is associated to a block device, contains the major and minor numbers of the device node, separated by ":" and prefixed by "b". Similarly for character devices, but prefixed by "c". For network devices, this is the interface index prefixed by "n". For all other devices, this is the subsystem name prefixed by "+", followed by ":", followed by the kernel device name. + +- name: journald.kernel.device_name + type: keyword + description: > + The kernel device name as it shows up in the device tree below `/sys/`. + +- name: journald.kernel.device_node_path + type: keyword + description: > + The device node path of this device in `/dev/`. + +- name: journald.kernel.device_symlinks + type: keyword + description: > + Additional symlink names pointing to the device node in `/dev/`. This field is frequently set more than once per entry. + +- name: journald.kernel.subsystem + type: keyword + description: > + The kernel subsystem name. + +- name: journald.object.pid + type: long + description: > + Privileged programs (currently UID 0) may attach OBJECT_PID= to a message. This will instruct systemd-journald to attach additional `journald.object.*` on behalf of the caller. These additional fields added automatically by systemd-journald. These additional `journald.object.*` fields are the same as the equivalent `journald.*` field except that the process identified by PID is described, instead of the process which logged the message. + +- name: journald.object.audit.login_uid + type: long +- name: journald.object.audit.session + type: long +- name: journald.object.gid + type: long +- name: journald.object.process.command_line + type: keyword +- name: journald.object.process.executable + type: keyword +- name: journald.object.process.name + type: keyword +- name: journald.object.systemd.owner_uid + type: long +- name: journald.object.systemd.session + type: keyword +- name: journald.object.systemd.unit + type: keyword +- name: journald.object.systemd.user_unit + type: keyword +- name: journald.object.uid + type: long +- name: journald.pid + type: long + description: > + The process ID of the process the journal entry originates from formatted as a decimal string. Note that entries obtained via "stdout" or "stderr" of forked processes will contain credentials valid for a parent process. + +- name: journald.process.capabilities + type: keyword + description: The effective capabilities(7) of the process the journal entry originates from. +- name: journald.process.command_line + type: keyword + description: > + The command line of the process the journal entry originates from. + +- name: journald.process.executable + type: keyword + description: > + The executable path of the process the journal entry originates from. + +- name: journald.process.name + type: keyword + description: > + The name of the process the journal entry originates from. + +- name: journald.uid + type: long + description: > + The user ID of the process the journal entry originates from formatted as a decimal string. Note that entries obtained via "stdout" or "stderr" of forked processes will contain credentials valid for a parent process. + +- name: log.syslog.identifier + type: keyword + description: > + Identifier (usually process) contained in the syslog header. + +- name: log.syslog.pid + type: long + description: > + PID contained in the syslog header. + +- name: systemd.cgroup + type: keyword + description: > + The control group path in the systemd hierarchy. + +- name: systemd.invocation_id + type: keyword + description: > + The invocation ID for the runtime cycle of the unit the message was generated in, as available to processes of the unit in $INVOCATION_ID. + +- name: systemd.owner_uid + type: long + description: > + The owner UID of the systemd user unit or systemd session (if any) of the process the journal entry originates from. + +- name: systemd.session + type: keyword + description: > + The systemd session ID (if any). + +- name: systemd.slice + type: keyword + description: > + The systemd slice unit name. + +- name: systemd.transport + type: keyword + description: > + How the entry was received by the journal service. + +- name: systemd.unit + type: keyword + description: > + The systemd unit name. + +- name: systemd.user_slice + type: keyword + description: > + The systemd user slice name. + +- name: systemd.user_unit + type: keyword + description: > + The unit name in the systemd user manager (if any). + +- name: journald.custom + type: flattened + description: >- + Structured fields added to the log message by the caller. diff --git a/packages/journald/data_stream/log/manifest.yml b/packages/journald/data_stream/log/manifest.yml new file mode 100644 index 000000000000..ebe6eeaab407 --- /dev/null +++ b/packages/journald/data_stream/log/manifest.yml @@ -0,0 +1,41 @@ +title: "Journald Log" +type: logs +streams: + - input: journald + title: Journald logs + template_path: journald.yml.hbs + description: Collect journald logs + vars: + - name: include_matches + type: text + title: Include Matches + multi: true + show_user: true + description: > + A list of filter expressions used to select the logs to read (e.g. `_SYSTEMD_UNIT=vault.service`). Defaults to all logs. See [include_matches](https://www.elastic.co/guide/en/beats/filebeat/7.x/filebeat-input-journald.html#filebeat-input-journald-include-matches) for details. + + - name: paths + type: text + title: Journal paths + multi: true + show_user: false + description: > + List of journals to read from. Defaults to the system journal. + + - name: tags + type: text + title: Tags + multi: true + required: true + show_user: false + default: + - journald-log + - name: processors + type: yaml + title: Processors + multi: false + required: false + show_user: false + description: > + Processors are used to reduce the number of fields in the exported event or to enhance the event with metadata. This executes in the agent before the logs are parsed. See [Processors](https://www.elastic.co/guide/en/beats/filebeat/current/filtering-and-enhancing-data.html) for details. + diff --git a/packages/journald/docs/README.md b/packages/journald/docs/README.md new file mode 100644 index 000000000000..8a54dca8fc8f --- /dev/null +++ b/packages/journald/docs/README.md @@ -0,0 +1,76 @@ +# Journald Input + +The journald input integration reads logs from the `journald` system service. +The journald input reads the log data and the metadata associated with it. + +The journald input is available on Linux systems with `systemd` installed. + +**Exported fields** + +| Field | Description | Type | +|---|---|---| +| @timestamp | Event timestamp. | date | +| container.log.tag | User defined tag of a container. Originates from the Docker journald logging driver. | keyword | +| container.partial | A field that flags log integrity when a message is split. The docker journald logging driver splits long message into multiple events. | boolean | +| data_stream.dataset | Data stream dataset. | constant_keyword | +| data_stream.namespace | Data stream namespace. | constant_keyword | +| data_stream.type | Data stream type. | constant_keyword | +| ecs.version | ECS version this event conforms to. `ecs.version` is a required field and must exist in all events. When querying across multiple indices -- which may conform to slightly different ECS versions -- this field lets integrations adjust to the schema version of the events. | keyword | +| host.hostname | The name of the originating host (from journald). | keyword | +| host.id | The machine ID of the originating host (from `machine-id`). | keyword | +| input.type | | keyword | +| journald.audit.login_uid | The login UID of the process the journal entry originates from, as maintained by the kernel audit subsystem. | long | +| journald.audit.session | The session of the process the journal entry originates from, as maintained by the kernel audit subsystem. | keyword | +| journald.code.file | The code location generating this message, if known. Contains the source filename. | keyword | +| journald.code.func | The code location generating this message, if known. Contains the function name. | keyword | +| journald.code.line | The code location generating this message, if known. Contains the line number. | long | +| journald.coredump.unit | Used to annotate messages containing coredumps from system units. | keyword | +| journald.coredump.user_unit | Used to annotate messages containing coredumps from user units. | keyword | +| journald.custom | Structured fields added to the log message by the caller. | flattened | +| journald.gid | The group ID of the process the journal entry originates from formatted as a decimal string. Note that entries obtained via "stdout" or "stderr" of forked processes will contain credentials valid for a parent process. | long | +| journald.host.boot_id | The kernel boot ID for the boot the message was generated in, formatted as a 128-bit hexadecimal string. | keyword | +| journald.kernel.device | The kernel device name. If the entry is associated to a block device, contains the major and minor numbers of the device node, separated by ":" and prefixed by "b". Similarly for character devices, but prefixed by "c". For network devices, this is the interface index prefixed by "n". For all other devices, this is the subsystem name prefixed by "+", followed by ":", followed by the kernel device name. | keyword | +| journald.kernel.device_name | The kernel device name as it shows up in the device tree below `/sys/`. | keyword | +| journald.kernel.device_node_path | The device node path of this device in `/dev/`. | keyword | +| journald.kernel.device_symlinks | Additional symlink names pointing to the device node in `/dev/`. This field is frequently set more than once per entry. | keyword | +| journald.kernel.subsystem | The kernel subsystem name. | keyword | +| journald.object.audit.login_uid | | long | +| journald.object.audit.session | | long | +| journald.object.gid | | long | +| journald.object.pid | Privileged programs (currently UID 0) may attach OBJECT_PID= to a message. This will instruct systemd-journald to attach additional `journald.object.\*` on behalf of the caller. These additional fields added automatically by systemd-journald. These additional `journald.object.\*` fields are the same as the equivalent `journald.\*` field except that the process identified by PID is described, instead of the process which logged the message. | long | +| journald.object.process.command_line | | keyword | +| journald.object.process.executable | | keyword | +| journald.object.process.name | | keyword | +| journald.object.systemd.owner_uid | | long | +| journald.object.systemd.session | | keyword | +| journald.object.systemd.unit | | keyword | +| journald.object.systemd.user_unit | | keyword | +| journald.object.uid | | long | +| journald.pid | The process ID of the process the journal entry originates from formatted as a decimal string. Note that entries obtained via "stdout" or "stderr" of forked processes will contain credentials valid for a parent process. | long | +| journald.process.capabilities | The effective capabilities(7) of the process the journal entry originates from. | keyword | +| journald.process.command_line | The command line of the process the journal entry originates from. | keyword | +| journald.process.executable | The executable path of the process the journal entry originates from. | keyword | +| journald.process.name | The name of the process the journal entry originates from. | keyword | +| journald.uid | The user ID of the process the journal entry originates from formatted as a decimal string. Note that entries obtained via "stdout" or "stderr" of forked processes will contain credentials valid for a parent process. | long | +| log.syslog.facility.code | The Syslog numeric facility of the log event, if available. According to RFCs 5424 and 3164, this value should be an integer between 0 and 23. | long | +| log.syslog.identifier | Identifier (usually process) contained in the syslog header. | keyword | +| log.syslog.pid | PID contained in the syslog header. | long | +| log.syslog.priority | Syslog numeric priority of the event, if available. According to RFCs 5424 and 3164, the priority is 8 \* facility + severity. This number is therefore expected to contain a value between 0 and 191. | long | +| message | For log events the message field contains the log message, optimized for viewing in a log viewer. For structured logs without an original message field, other fields can be concatenated to form a human-readable summary of the event. If multiple messages exist, they can be combined into one message. | text | +| process.args | Array of process arguments, starting with the absolute path to the executable. May be filtered to protect sensitive information. | keyword | +| process.args_count | Length of the process.args array. This field can be useful for querying or performing bucket analysis on how many arguments were provided to start a process. More arguments may be an indication of suspicious activity. | long | +| process.command_line | Full command line that started the process, including the absolute path to the executable, and all arguments. Some arguments may be filtered to protect sensitive information. | keyword | +| process.pid | Process id. | long | +| systemd.cgroup | The control group path in the systemd hierarchy. | keyword | +| systemd.invocation_id | The invocation ID for the runtime cycle of the unit the message was generated in, as available to processes of the unit in $INVOCATION_ID. | keyword | +| systemd.owner_uid | The owner UID of the systemd user unit or systemd session (if any) of the process the journal entry originates from. | long | +| systemd.session | The systemd session ID (if any). | keyword | +| systemd.slice | The systemd slice unit name. | keyword | +| systemd.transport | How the entry was received by the journal service. | keyword | +| systemd.unit | The systemd unit name. | keyword | +| systemd.user_slice | The systemd user slice name. | keyword | +| systemd.user_unit | The unit name in the systemd user manager (if any). | keyword | +| tags | List of keywords used to tag each event. | keyword | +| user.group.id | Unique identifier for the group on the system/platform. | keyword | +| user.id | Unique identifier of the user. | keyword | + diff --git a/packages/journald/img/systemd-logo.svg b/packages/journald/img/systemd-logo.svg new file mode 100644 index 000000000000..24278b6978bf --- /dev/null +++ b/packages/journald/img/systemd-logo.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/packages/journald/manifest.yml b/packages/journald/manifest.yml new file mode 100644 index 000000000000..66a1919d1629 --- /dev/null +++ b/packages/journald/manifest.yml @@ -0,0 +1,27 @@ +format_version: 1.0.0 +name: journald +title: "Custom Journald logs" +version: 0.0.1 +license: basic +description: "This Elastic integration collects custom jourald logs" +type: integration +categories: + - custom +release: experimental +conditions: + kibana.version: "^7.16.0" +icons: + - src: /img/systemd-logo.svg + title: systemd logo + size: 32x32 + type: image/svg+xml +policy_templates: + - name: logs + title: Journald + description: Collect sample logs + inputs: + - type: journald + title: Journald logs + description: Collect journald logs +owner: + github: elastic/integrations