diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_apache2.test.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_apache2.test.ts index 921153f54497..715051521b01 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_apache2.test.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_apache2.test.ts @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ +import { builtinRules } from '.'; import { compileFormattingRules } from '../message'; -import { filebeatApache2Rules } from './filebeat_apache2'; -const { format } = compileFormattingRules(filebeatApache2Rules); +const { format } = compileFormattingRules(builtinRules); describe('Filebeat Rules', () => { describe('in ECS format', () => { @@ -45,7 +45,15 @@ describe('Filebeat Rules', () => { expect(format(flattenedDocument)).toMatchInlineSnapshot(` Array [ Object { - "constant": "[Apache][access] ", + "constant": "[", + }, + Object { + "field": "event.module", + "highlights": Array [], + "value": "apache", + }, + Object { + "constant": "][access] ", }, Object { "field": "source.ip", @@ -123,7 +131,7 @@ Array [ expect(format(flattenedDocument)).toMatchInlineSnapshot(` Array [ Object { - "constant": "[Apache][", + "constant": "[apache][", }, Object { "field": "log.level", @@ -159,7 +167,7 @@ Array [ expect(format(flattenedDocument)).toMatchInlineSnapshot(` Array [ Object { - "constant": "[Apache][access] ", + "constant": "[apache][access] ", }, Object { "field": "apache2.access.remote_ip", @@ -228,7 +236,7 @@ Array [ expect(format(flattenedDocument)).toMatchInlineSnapshot(` Array [ Object { - "constant": "[Apache][", + "constant": "[apache][", }, Object { "field": "apache2.error.level", diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_apache2.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_apache2.ts index 6f9e58de0dc8..fe7ebffe9132 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_apache2.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_apache2.ts @@ -5,58 +5,6 @@ */ export const filebeatApache2Rules = [ - { - // ECS - when: { - values: { - 'event.dataset': 'apache.access', - }, - }, - format: [ - { - constant: '[Apache][access] ', - }, - { - field: 'source.ip', - }, - { - constant: ' ', - }, - { - field: 'user.name', - }, - { - constant: ' "', - }, - { - field: 'http.request.method', - }, - { - constant: ' ', - }, - { - field: 'url.original', - }, - { - constant: ' HTTP/', - }, - { - field: 'http.version', - }, - { - constant: '" ', - }, - { - field: 'http.response.status_code', - }, - { - constant: ' ', - }, - { - field: 'http.response.body.bytes', - }, - ], - }, { // pre-ECS when: { @@ -64,7 +12,7 @@ export const filebeatApache2Rules = [ }, format: [ { - constant: '[Apache][access] ', + constant: '[apache][access] ', }, { field: 'apache2.access.remote_ip', @@ -116,7 +64,7 @@ export const filebeatApache2Rules = [ }, format: [ { - constant: '[Apache][', + constant: '[apache][', }, { field: 'log.level', @@ -136,7 +84,7 @@ export const filebeatApache2Rules = [ }, format: [ { - constant: '[Apache][', + constant: '[apache][', }, { field: 'apache2.error.level', diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_auditd.test.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_auditd.test.ts index f40081ab52b7..49ab51bdce05 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_auditd.test.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_auditd.test.ts @@ -10,141 +10,350 @@ import { filebeatAuditdRules } from './filebeat_auditd'; const { format } = compileFormattingRules(filebeatAuditdRules); describe('Filebeat Rules', () => { - test('auditd IPSEC rule', () => { - const event = { - '@timestamp': '2017-01-31T20:17:14.891Z', - 'auditd.log.auid': '4294967295', - 'auditd.log.dst': '192.168.0.0', - 'auditd.log.dst_prefixlen': '16', - 'auditd.log.op': 'SPD-delete', - 'auditd.log.record_type': 'MAC_IPSEC_EVENT', - 'auditd.log.res': '1', - 'auditd.log.sequence': 18877201, - 'auditd.log.ses': '4294967295', - 'auditd.log.src': '192.168.2.0', - 'auditd.log.src_prefixlen': '24', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'auditd.log', - 'event.module': 'auditd', - 'fileset.name': 'log', - 'input.type': 'log', - 'log.offset': 0, - }; - const message = format(event); - expect(message).toEqual([ - { constant: '[AuditD][' }, - { field: 'auditd.log.record_type', highlights: [], value: 'MAC_IPSEC_EVENT' }, - { constant: '] src:' }, - { field: 'auditd.log.src', highlights: [], value: '192.168.2.0' }, - { constant: ' dst:' }, - { field: 'auditd.log.dst', highlights: [], value: '192.168.0.0' }, - { constant: ' op:' }, - { field: 'auditd.log.op', highlights: [], value: 'SPD-delete' }, - ]); - }); + describe('in ECS format', () => { + test('auditd log with outcome', () => { + const flattenedDocument = { + '@timestamp': '2016-12-07T02:17:21.515Z', + 'auditd.log': { + addr: '96.241.146.97', + cipher: 'chacha20-poly1305@openssh.com', + direction: 'from-server', + ksize: '512', + laddr: '10.142.0.2', + lport: '22', + pfs: 'curve25519-sha256@libssh.org', + rport: '63927', + sequence: 406, + ses: '4294967295', + spid: '1299', + subj: 'system_u:system_r:sshd_t:s0-s0:c0.c1023', + }, + 'ecs.version': '1.0.0-beta2', + 'event.action': 'crypto_session', + 'event.dataset': 'auditd.log', + 'event.module': 'auditd', + 'event.outcome': 'success', + 'fileset.name': 'log', + 'input.type': 'log', + 'log.offset': 783, + message: 'op=start', + process: { executable: '/usr/sbin/sshd', pid: 1298 }, + 'service.type': 'auditd', + user: { 'audit.id': '4294967295', id: '0', 'saved.id': '74' }, + }; - test('AuditD SYSCALL rule', () => { - const event = { - '@timestamp': '2017-01-31T20:17:14.891Z', - 'auditd.log.a0': '9', - 'auditd.log.a1': '7f564b2672a0', - 'auditd.log.a2': 'b8', - 'auditd.log.a3': '0', - 'auditd.log.arch': 'x86_64', - 'auditd.log.auid': '4294967295', - 'auditd.log.comm': 'charon', - 'auditd.log.egid': '0', - 'auditd.log.euid': '0', - 'auditd.log.exe': '/usr/libexec/strongswan/charon (deleted)', - 'auditd.log.exit': '184', - 'auditd.log.fsgid': '0', - 'auditd.log.fsuid': '0', - 'auditd.log.gid': '0', - 'auditd.log.items': '0', - 'auditd.log.pid': '1281', - 'auditd.log.ppid': '1240', - 'auditd.log.record_type': 'SYSCALL', - 'auditd.log.sequence': 18877199, - 'auditd.log.ses': '4294967295', - 'auditd.log.sgid': '0', - 'auditd.log.success': 'yes', - 'auditd.log.suid': '0', - 'auditd.log.syscall': '44', - 'auditd.log.tty': '(none)', - 'auditd.log.uid': '0', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'auditd.log', - 'event.module': 'auditd', - 'fileset.name': 'log', - 'input.type': 'log', - 'log.offset': 174, - }; - const message = format(event); - expect(message).toEqual([ - { constant: '[AuditD][' }, - { field: 'auditd.log.record_type', highlights: [], value: 'SYSCALL' }, - { constant: '] exe:' }, - { - field: 'auditd.log.exe', - highlights: [], - value: '/usr/libexec/strongswan/charon (deleted)', - }, - { constant: ' gid:' }, - { field: 'auditd.log.gid', highlights: [], value: '0' }, - { constant: ' uid:' }, - { field: 'auditd.log.uid', highlights: [], value: '0' }, - { constant: ' tty:' }, - { field: 'auditd.log.tty', highlights: [], value: '(none)' }, - { constant: ' pid:' }, - { field: 'auditd.log.pid', highlights: [], value: '1281' }, - { constant: ' ppid:' }, - { field: 'auditd.log.ppid', highlights: [], value: '1240' }, - ]); - }); + expect(format(flattenedDocument)).toMatchInlineSnapshot(` +Array [ + Object { + "constant": "[AuditD][", + }, + Object { + "field": "event.action", + "highlights": Array [], + "value": "crypto_session", + }, + Object { + "constant": "]", + }, + Object { + "constant": " ", + }, + Object { + "field": "event.outcome", + "highlights": Array [], + "value": "success", + }, + Object { + "constant": " ", + }, + Object { + "constant": "user", + }, + Object { + "constant": "=", + }, + Object { + "field": "user", + "highlights": Array [], + "value": "{\\"audit.id\\":\\"4294967295\\",\\"id\\":\\"0\\",\\"saved.id\\":\\"74\\"}", + }, + Object { + "constant": " ", + }, + Object { + "constant": "process", + }, + Object { + "constant": "=", + }, + Object { + "field": "process", + "highlights": Array [], + "value": "{\\"executable\\":\\"/usr/sbin/sshd\\",\\"pid\\":1298}", + }, + Object { + "constant": " ", + }, + Object { + "field": "auditd.log", + "highlights": Array [], + "value": "{\\"addr\\":\\"96.241.146.97\\",\\"cipher\\":\\"chacha20-poly1305@openssh.com\\",\\"direction\\":\\"from-server\\",\\"ksize\\":\\"512\\",\\"laddr\\":\\"10.142.0.2\\",\\"lport\\":\\"22\\",\\"pfs\\":\\"curve25519-sha256@libssh.org\\",\\"rport\\":\\"63927\\",\\"sequence\\":406,\\"ses\\":\\"4294967295\\",\\"spid\\":\\"1299\\",\\"subj\\":\\"system_u:system_r:sshd_t:s0-s0:c0.c1023\\"}", + }, + Object { + "constant": " ", + }, + Object { + "field": "message", + "highlights": Array [], + "value": "op=start", + }, +] +`); + }); + + test('auditd log without outcome', () => { + const flattenedDocument = { + '@timestamp': '2017-01-31T20:17:14.891Z', + 'auditd.log': { + a0: '9', + a1: '7f564b2672a0', + a2: 'b8', + a3: '0', + exit: '184', + items: '0', + sequence: 18877199, + ses: '4294967295', + success: 'yes', + syscall: '44', + tty: '(none)', + }, + 'ecs.version': '1.0.0-beta2', + 'event.action': 'syscall', + 'event.dataset': 'auditd.log', + 'event.module': 'auditd', + 'fileset.name': 'log', + 'host.architecture': 'x86_64', + 'input.type': 'log', + 'log.offset': 174, + process: { + executable: '/usr/libexec/strongswan/charon (deleted)', + name: 'charon', + pid: 1281, + ppid: 1240, + }, + 'service.type': 'auditd', + user: { + 'audit.id': '4294967295', + 'effective.group.id': '0', + 'effective.id': '0', + 'filesystem.group.id': '0', + 'filesystem.id': '0', + 'group.id': '0', + id: '0', + 'saved.group.id': '0', + 'saved.id': '0', + }, + }; - test('AuditD events with msg rule', () => { - const event = { - '@timestamp': '2017-01-31T20:17:14.891Z', - 'auditd.log.auid': '4294967295', - 'auditd.log.record_type': 'EXAMPLE', - 'auditd.log.msg': 'some kind of message', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'auditd.log', - 'event.module': 'auditd', - 'fileset.name': 'log', - 'input.type': 'log', - 'log.offset': 174, - }; - const message = format(event); - expect(message).toEqual([ - { constant: '[AuditD][' }, - { field: 'auditd.log.record_type', highlights: [], value: 'EXAMPLE' }, - { constant: '] ' }, - { - field: 'auditd.log.msg', - highlights: [], - value: 'some kind of message', - }, - ]); + expect(format(flattenedDocument)).toMatchInlineSnapshot(` +Array [ + Object { + "constant": "[AuditD][", + }, + Object { + "field": "event.action", + "highlights": Array [], + "value": "syscall", + }, + Object { + "constant": "]", + }, + Object { + "constant": " ", + }, + Object { + "constant": "user", + }, + Object { + "constant": "=", + }, + Object { + "field": "user", + "highlights": Array [], + "value": "{\\"audit.id\\":\\"4294967295\\",\\"effective.group.id\\":\\"0\\",\\"effective.id\\":\\"0\\",\\"filesystem.group.id\\":\\"0\\",\\"filesystem.id\\":\\"0\\",\\"group.id\\":\\"0\\",\\"id\\":\\"0\\",\\"saved.group.id\\":\\"0\\",\\"saved.id\\":\\"0\\"}", + }, + Object { + "constant": " ", + }, + Object { + "constant": "process", + }, + Object { + "constant": "=", + }, + Object { + "field": "process", + "highlights": Array [], + "value": "{\\"executable\\":\\"/usr/libexec/strongswan/charon (deleted)\\",\\"name\\":\\"charon\\",\\"pid\\":1281,\\"ppid\\":1240}", + }, + Object { + "constant": " ", + }, + Object { + "field": "auditd.log", + "highlights": Array [], + "value": "{\\"a0\\":\\"9\\",\\"a1\\":\\"7f564b2672a0\\",\\"a2\\":\\"b8\\",\\"a3\\":\\"0\\",\\"exit\\":\\"184\\",\\"items\\":\\"0\\",\\"sequence\\":18877199,\\"ses\\":\\"4294967295\\",\\"success\\":\\"yes\\",\\"syscall\\":\\"44\\",\\"tty\\":\\"(none)\\"}", + }, + Object { + "constant": " ", + }, + Object { + "field": "message", + "highlights": Array [], + "value": "undefined", + }, +] +`); + }); }); - test('AuditD catchall rule', () => { - const event = { - '@timestamp': '2017-01-31T20:17:14.891Z', - 'auditd.log.auid': '4294967295', - 'auditd.log.record_type': 'EXAMPLE', - 'ecs.version': '1.0.0-beta2', - 'event.dataset': 'auditd.log', - 'event.module': 'auditd', - 'fileset.name': 'log', - 'input.type': 'log', - 'log.offset': 174, - }; - const message = format(event); - expect(message).toEqual([ - { constant: '[AuditD][' }, - { field: 'auditd.log.record_type', highlights: [], value: 'EXAMPLE' }, - { constant: '] Event without message.' }, - ]); + describe('in pre-ECS format', () => { + test('auditd IPSEC rule', () => { + const event = { + '@timestamp': '2017-01-31T20:17:14.891Z', + 'auditd.log.auid': '4294967295', + 'auditd.log.dst': '192.168.0.0', + 'auditd.log.dst_prefixlen': '16', + 'auditd.log.op': 'SPD-delete', + 'auditd.log.record_type': 'MAC_IPSEC_EVENT', + 'auditd.log.res': '1', + 'auditd.log.sequence': 18877201, + 'auditd.log.ses': '4294967295', + 'auditd.log.src': '192.168.2.0', + 'auditd.log.src_prefixlen': '24', + 'ecs.version': '1.0.0-beta2', + 'event.dataset': 'auditd.log', + 'event.module': 'auditd', + 'fileset.name': 'log', + 'input.type': 'log', + 'log.offset': 0, + }; + const message = format(event); + expect(message).toEqual([ + { constant: '[AuditD][' }, + { field: 'auditd.log.record_type', highlights: [], value: 'MAC_IPSEC_EVENT' }, + { constant: '] src:' }, + { field: 'auditd.log.src', highlights: [], value: '192.168.2.0' }, + { constant: ' dst:' }, + { field: 'auditd.log.dst', highlights: [], value: '192.168.0.0' }, + { constant: ' op:' }, + { field: 'auditd.log.op', highlights: [], value: 'SPD-delete' }, + ]); + }); + + test('AuditD SYSCALL rule', () => { + const event = { + '@timestamp': '2017-01-31T20:17:14.891Z', + 'auditd.log.a0': '9', + 'auditd.log.a1': '7f564b2672a0', + 'auditd.log.a2': 'b8', + 'auditd.log.a3': '0', + 'auditd.log.arch': 'x86_64', + 'auditd.log.auid': '4294967295', + 'auditd.log.comm': 'charon', + 'auditd.log.egid': '0', + 'auditd.log.euid': '0', + 'auditd.log.exe': '/usr/libexec/strongswan/charon (deleted)', + 'auditd.log.exit': '184', + 'auditd.log.fsgid': '0', + 'auditd.log.fsuid': '0', + 'auditd.log.gid': '0', + 'auditd.log.items': '0', + 'auditd.log.pid': '1281', + 'auditd.log.ppid': '1240', + 'auditd.log.record_type': 'SYSCALL', + 'auditd.log.sequence': 18877199, + 'auditd.log.ses': '4294967295', + 'auditd.log.sgid': '0', + 'auditd.log.success': 'yes', + 'auditd.log.suid': '0', + 'auditd.log.syscall': '44', + 'auditd.log.tty': '(none)', + 'auditd.log.uid': '0', + 'ecs.version': '1.0.0-beta2', + 'event.dataset': 'auditd.log', + 'event.module': 'auditd', + 'fileset.name': 'log', + 'input.type': 'log', + 'log.offset': 174, + }; + const message = format(event); + expect(message).toEqual([ + { constant: '[AuditD][' }, + { field: 'auditd.log.record_type', highlights: [], value: 'SYSCALL' }, + { constant: '] exe:' }, + { + field: 'auditd.log.exe', + highlights: [], + value: '/usr/libexec/strongswan/charon (deleted)', + }, + { constant: ' gid:' }, + { field: 'auditd.log.gid', highlights: [], value: '0' }, + { constant: ' uid:' }, + { field: 'auditd.log.uid', highlights: [], value: '0' }, + { constant: ' tty:' }, + { field: 'auditd.log.tty', highlights: [], value: '(none)' }, + { constant: ' pid:' }, + { field: 'auditd.log.pid', highlights: [], value: '1281' }, + { constant: ' ppid:' }, + { field: 'auditd.log.ppid', highlights: [], value: '1240' }, + ]); + }); + + test('AuditD events with msg rule', () => { + const event = { + '@timestamp': '2017-01-31T20:17:14.891Z', + 'auditd.log.auid': '4294967295', + 'auditd.log.record_type': 'EXAMPLE', + 'auditd.log.msg': 'some kind of message', + 'ecs.version': '1.0.0-beta2', + 'event.dataset': 'auditd.log', + 'event.module': 'auditd', + 'fileset.name': 'log', + 'input.type': 'log', + 'log.offset': 174, + }; + const message = format(event); + expect(message).toEqual([ + { constant: '[AuditD][' }, + { field: 'auditd.log.record_type', highlights: [], value: 'EXAMPLE' }, + { constant: '] ' }, + { + field: 'auditd.log.msg', + highlights: [], + value: 'some kind of message', + }, + ]); + }); + + test('AuditD catchall rule', () => { + const event = { + '@timestamp': '2017-01-31T20:17:14.891Z', + 'auditd.log.auid': '4294967295', + 'auditd.log.record_type': 'EXAMPLE', + 'ecs.version': '1.0.0-beta2', + 'event.dataset': 'auditd.log', + 'event.module': 'auditd', + 'fileset.name': 'log', + 'input.type': 'log', + 'log.offset': 174, + }; + const message = format(event); + expect(message).toEqual([ + { constant: '[AuditD][' }, + { field: 'auditd.log.record_type', highlights: [], value: 'EXAMPLE' }, + { constant: '] Event without message.' }, + ]); + }); }); }); diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_auditd.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_auditd.ts index d8893136e9bb..d2557cf1599c 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_auditd.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_auditd.ts @@ -3,9 +3,46 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + +import { labelField } from './helpers'; + +const commonActionField = [{ constant: '[AuditD][' }, { field: 'event.action' }, { constant: ']' }]; +const commonOutcomeField = [{ constant: ' ' }, { field: 'event.outcome' }]; + export const filebeatAuditdRules = [ - // IPSEC_EVENT Rule { + // ECS format with outcome + when: { + exists: ['ecs.version', 'event.action', 'event.outcome', 'auditd.log'], + }, + format: [ + ...commonActionField, + ...commonOutcomeField, + ...labelField('user', 'user'), + ...labelField('process', 'process'), + { constant: ' ' }, + { field: 'auditd.log' }, + { constant: ' ' }, + { field: 'message' }, + ], + }, + { + // ECS format without outcome + when: { + exists: ['ecs.version', 'event.action', 'auditd.log'], + }, + format: [ + ...commonActionField, + ...labelField('user', 'user'), + ...labelField('process', 'process'), + { constant: ' ' }, + { field: 'auditd.log' }, + { constant: ' ' }, + { field: 'message' }, + ], + }, + { + // pre-ECS IPSEC_EVENT Rule when: { exists: ['auditd.log.record_type', 'auditd.log.src', 'auditd.log.dst', 'auditd.log.op'], values: { @@ -23,8 +60,8 @@ export const filebeatAuditdRules = [ { field: 'auditd.log.op' }, ], }, - // SYSCALL Rule { + // pre-ECS SYSCALL Rule when: { exists: [ 'auditd.log.record_type', @@ -56,8 +93,8 @@ export const filebeatAuditdRules = [ { field: 'auditd.log.ppid' }, ], }, - // Events with `msg` Rule { + // pre-ECS Events with `msg` Rule when: { exists: ['auditd.log.record_type', 'auditd.log.msg'], }, @@ -68,8 +105,8 @@ export const filebeatAuditdRules = [ { field: 'auditd.log.msg' }, ], }, - // Events with `msg` Rule { + // pre-ECS Events with `msg` Rule when: { exists: ['auditd.log.record_type'], }, diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_haproxy.test.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_haproxy.test.ts index ab39af635976..bf62463aa947 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_haproxy.test.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_haproxy.test.ts @@ -10,6 +10,400 @@ import { filebeatHaproxyRules } from './filebeat_haproxy'; const { format } = compileFormattingRules(filebeatHaproxyRules); describe('Filebeat Rules', () => { + describe('in ECS format', () => { + test('haproxy default log', () => { + const flattenedDocument = { + 'destination.ip': '1.2.3.4', + 'destination.port': 5000, + 'ecs.version': '1.0.0-beta2', + 'event.dataset': 'haproxy.log', + 'event.module': 'haproxy', + 'fileset.name': 'log', + 'haproxy.frontend_name': 'main', + 'haproxy.mode': 'HTTP', + 'haproxy.source': '1.2.3.4', + 'input.type': 'log', + 'log.offset': 0, + 'process.name': 'haproxy', + 'process.pid': 24551, + 'service.type': 'haproxy', + 'source.address': '1.2.3.4', + 'source.geo.continent_name': 'North America', + 'source.geo.country_iso_code': 'US', + 'source.geo.location.lat': 37.751, + 'source.geo.location.lon': -97.822, + 'source.ip': '1.2.3.4', + 'source.port': 40780, + }; + + expect(format(flattenedDocument)).toMatchInlineSnapshot(` +Array [ + Object { + "constant": "[HAProxy] ", + }, + Object { + "field": "source.address", + "highlights": Array [], + "value": "1.2.3.4", + }, + Object { + "constant": ":", + }, + Object { + "field": "source.port", + "highlights": Array [], + "value": "40780", + }, + Object { + "constant": " ", + }, + Object { + "field": "haproxy.frontend_name", + "highlights": Array [], + "value": "main", + }, +] +`); + }); + + test('haproxy tcp log', () => { + const flattenedDocument = { + 'ecs.version': '1.0.0-beta2', + 'event.dataset': 'haproxy.log', + 'event.duration': 1000000, + 'event.module': 'haproxy', + 'fileset.name': 'log', + 'haproxy.backend_name': 'app', + 'haproxy.backend_queue': 0, + 'haproxy.bytes_read': 212, + 'haproxy.connection_wait_time_ms': -1, + 'haproxy.connections.active': 1, + 'haproxy.connections.backend': 0, + 'haproxy.connections.frontend': 1, + 'haproxy.connections.retries': 0, + 'haproxy.connections.server': 0, + 'haproxy.frontend_name': 'main', + 'haproxy.server_name': '', + 'haproxy.server_queue': 0, + 'haproxy.source': '127.0.0.1', + 'haproxy.termination_state': 'SC', + 'haproxy.total_waiting_time_ms': -1, + 'input.type': 'log', + 'log.offset': 0, + 'process.name': 'haproxy', + 'process.pid': 25457, + 'service.type': 'haproxy', + 'source.address': '127.0.0.1', + 'source.ip': '127.0.0.1', + 'source.port': 40962, + }; + + expect(format(flattenedDocument)).toMatchInlineSnapshot(` +Array [ + Object { + "constant": "[HAProxy][tcp] ", + }, + Object { + "field": "source.address", + "highlights": Array [], + "value": "127.0.0.1", + }, + Object { + "constant": ":", + }, + Object { + "field": "source.port", + "highlights": Array [], + "value": "40962", + }, + Object { + "constant": " ", + }, + Object { + "field": "haproxy.frontend_name", + "highlights": Array [], + "value": "main", + }, + Object { + "constant": " -> ", + }, + Object { + "field": "haproxy.backend_name", + "highlights": Array [], + "value": "app", + }, + Object { + "constant": "/", + }, + Object { + "field": "haproxy.server_name", + "highlights": Array [], + "value": "", + }, + Object { + "constant": " ", + }, + Object { + "field": "haproxy.connections.active", + "highlights": Array [], + "value": "1", + }, + Object { + "constant": "/", + }, + Object { + "field": "haproxy.connections.frontend", + "highlights": Array [], + "value": "1", + }, + Object { + "constant": "/", + }, + Object { + "field": "haproxy.connections.backend", + "highlights": Array [], + "value": "0", + }, + Object { + "constant": "/", + }, + Object { + "field": "haproxy.connections.server", + "highlights": Array [], + "value": "0", + }, + Object { + "constant": "/", + }, + Object { + "field": "haproxy.connections.retries", + "highlights": Array [], + "value": "0", + }, + Object { + "constant": " ", + }, + Object { + "field": "haproxy.server_queue", + "highlights": Array [], + "value": "0", + }, + Object { + "constant": "/", + }, + Object { + "field": "haproxy.backend_queue", + "highlights": Array [], + "value": "0", + }, +] +`); + }); + + test('haproxy http log', () => { + const flattenedDocument = { + 'ecs.version': '1.0.0-beta2', + 'event.dataset': 'haproxy.log', + 'event.duration': 2000000, + 'event.module': 'haproxy', + 'fileset.name': 'log', + 'haproxy.backend_name': 'docs_microservice', + 'haproxy.backend_queue': 0, + 'haproxy.bytes_read': 168, + 'haproxy.connection_wait_time_ms': 1, + 'haproxy.connections.active': 6, + 'haproxy.connections.backend': 0, + 'haproxy.connections.frontend': 6, + 'haproxy.connections.retries': 0, + 'haproxy.connections.server': 0, + 'haproxy.frontend_name': 'incoming~', + 'haproxy.http.request.captured_cookie': '-', + 'haproxy.http.request.captured_headers': ['docs.example.internal'], + 'haproxy.http.request.raw_request_line': + 'GET /component---src-pages-index-js-4b15624544f97cf0bb8f.js HTTP/1.1', + 'haproxy.http.request.time_wait_ms': 0, + 'haproxy.http.request.time_wait_without_data_ms': 0, + 'haproxy.http.response.captured_cookie': '-', + 'haproxy.http.response.captured_headers': [], + 'haproxy.server_name': 'docs', + 'haproxy.server_queue': 0, + 'haproxy.termination_state': '----', + 'haproxy.total_waiting_time_ms': 0, + 'http.response.bytes': 168, + 'http.response.status_code': 304, + 'input.type': 'log', + 'log.offset': 0, + 'process.name': 'haproxy', + 'process.pid': 32450, + 'service.type': 'haproxy', + 'source.address': '1.2.3.4', + 'source.geo.continent_name': 'North America', + 'source.geo.country_iso_code': 'US', + 'source.geo.location.lat': 37.751, + 'source.geo.location.lon': -97.822, + 'source.ip': '1.2.3.4', + 'source.port': 38862, + }; + + expect(format(flattenedDocument)).toMatchInlineSnapshot(` +Array [ + Object { + "constant": "[HAProxy][http] ", + }, + Object { + "field": "source.address", + "highlights": Array [], + "value": "1.2.3.4", + }, + Object { + "constant": ":", + }, + Object { + "field": "source.port", + "highlights": Array [], + "value": "38862", + }, + Object { + "constant": " ", + }, + Object { + "field": "haproxy.frontend_name", + "highlights": Array [], + "value": "incoming~", + }, + Object { + "constant": " -> ", + }, + Object { + "field": "haproxy.backend_name", + "highlights": Array [], + "value": "docs_microservice", + }, + Object { + "constant": "/", + }, + Object { + "field": "haproxy.server_name", + "highlights": Array [], + "value": "docs", + }, + Object { + "constant": " \\"", + }, + Object { + "field": "haproxy.http.request.raw_request_line", + "highlights": Array [], + "value": "GET /component---src-pages-index-js-4b15624544f97cf0bb8f.js HTTP/1.1", + }, + Object { + "constant": "\\" ", + }, + Object { + "field": "http.response.status_code", + "highlights": Array [], + "value": "304", + }, + Object { + "constant": " ", + }, + Object { + "field": "haproxy.http.request.time_wait_ms", + "highlights": Array [], + "value": "0", + }, + Object { + "constant": "/", + }, + Object { + "field": "event.duration", + "highlights": Array [], + "value": "2000000", + }, + Object { + "constant": "/", + }, + Object { + "field": "haproxy.connection_wait_time_ms", + "highlights": Array [], + "value": "1", + }, + Object { + "constant": "/", + }, + Object { + "field": "haproxy.http.request.time_wait_without_data_ms", + "highlights": Array [], + "value": "0", + }, + Object { + "constant": "/", + }, + Object { + "field": "event.duration", + "highlights": Array [], + "value": "2000000", + }, + Object { + "constant": " ", + }, + Object { + "field": "haproxy.connections.active", + "highlights": Array [], + "value": "6", + }, + Object { + "constant": "/", + }, + Object { + "field": "haproxy.connections.frontend", + "highlights": Array [], + "value": "6", + }, + Object { + "constant": "/", + }, + Object { + "field": "haproxy.connections.backend", + "highlights": Array [], + "value": "0", + }, + Object { + "constant": "/", + }, + Object { + "field": "haproxy.connections.server", + "highlights": Array [], + "value": "0", + }, + Object { + "constant": "/", + }, + Object { + "field": "haproxy.connections.retries", + "highlights": Array [], + "value": "0", + }, + Object { + "constant": " ", + }, + Object { + "field": "haproxy.server_queue", + "highlights": Array [], + "value": "0", + }, + Object { + "constant": "/", + }, + Object { + "field": "haproxy.backend_queue", + "highlights": Array [], + "value": "0", + }, +] +`); + }); + }); + describe('in pre-ECS format', () => { test('haproxy default log', () => { const flattenedDocument = { @@ -60,9 +454,6 @@ Array [ "highlights": Array [], "value": "main", }, - Object { - "constant": " ", - }, ] `); }); diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_haproxy.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_haproxy.ts index 79b778e9448e..97836b0a8186 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_haproxy.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_haproxy.ts @@ -4,7 +4,25 @@ * you may not use this file except in compliance with the Elastic License. */ -const commonFrontendFields = [ +const ecsFrontendFields = [ + { + field: 'source.address', + }, + { + constant: ':', + }, + { + field: 'source.port', + }, + { + constant: ' ', + }, + { + field: 'haproxy.frontend_name', + }, +]; + +const preEcsFrontendFields = [ { field: 'haproxy.client.ip', }, @@ -80,6 +98,120 @@ const commonQueueStatsFields = [ ]; export const filebeatHaproxyRules = [ + { + // ECS + when: { + exists: ['ecs.version', 'haproxy.http.request.raw_request_line'], + }, + format: [ + { + constant: '[HAProxy][http] ', + }, + ...ecsFrontendFields, + ...commonBackendFields, + { + constant: ' "', + }, + { + field: 'haproxy.http.request.raw_request_line', + }, + { + constant: '" ', + }, + { + field: 'http.response.status_code', + }, + { + constant: ' ', + }, + { + field: 'haproxy.http.request.time_wait_ms', + }, + { + constant: '/', + }, + { + field: 'event.duration', + }, + { + constant: '/', + }, + { + field: 'haproxy.connection_wait_time_ms', + }, + { + constant: '/', + }, + { + field: 'haproxy.http.request.time_wait_without_data_ms', + }, + { + constant: '/', + }, + { + field: 'event.duration', + }, + { + constant: ' ', + }, + ...commonConnectionStatsFields, + { + constant: ' ', + }, + ...commonQueueStatsFields, + ], + }, + { + // ECS + when: { + exists: ['ecs.version', 'haproxy.connections.active'], + }, + format: [ + { + constant: '[HAProxy][tcp] ', + }, + ...ecsFrontendFields, + ...commonBackendFields, + { + constant: ' ', + }, + ...commonConnectionStatsFields, + { + constant: ' ', + }, + ...commonQueueStatsFields, + ], + }, + { + // ECS + when: { + exists: ['ecs.version', 'haproxy.error_message'], + }, + format: [ + { + constant: '[HAProxy] ', + }, + ...ecsFrontendFields, + { + constant: ' ', + }, + { + field: 'haproxy.error_message', + }, + ], + }, + { + // ECS + when: { + exists: ['ecs.version', 'haproxy.frontend_name'], + }, + format: [ + { + constant: '[HAProxy] ', + }, + ...ecsFrontendFields, + ], + }, { // pre-ECS when: { @@ -89,7 +221,7 @@ export const filebeatHaproxyRules = [ { constant: '[HAProxy][http] ', }, - ...commonFrontendFields, + ...preEcsFrontendFields, ...commonBackendFields, { constant: ' "', @@ -152,7 +284,7 @@ export const filebeatHaproxyRules = [ { constant: '[HAProxy][tcp] ', }, - ...commonFrontendFields, + ...preEcsFrontendFields, ...commonBackendFields, { constant: ' ', @@ -173,7 +305,7 @@ export const filebeatHaproxyRules = [ { constant: '[HAProxy] ', }, - ...commonFrontendFields, + ...preEcsFrontendFields, { constant: ' ', }, @@ -191,10 +323,7 @@ export const filebeatHaproxyRules = [ { constant: '[HAProxy] ', }, - ...commonFrontendFields, - { - constant: ' ', - }, + ...preEcsFrontendFields, ], }, ]; diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_iis.test.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_iis.test.ts index 192736a138d4..4c90dc7c62f4 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_iis.test.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_iis.test.ts @@ -4,12 +4,295 @@ * you may not use this file except in compliance with the Elastic License. */ +import { builtinRules } from '.'; import { compileFormattingRules } from '../message'; -import { filebeatIisRules } from './filebeat_iis'; -const { format } = compileFormattingRules(filebeatIisRules); +const { format } = compileFormattingRules(builtinRules); describe('Filebeat Rules', () => { + describe('in ECS format', () => { + test('iis access log', () => { + const flattenedDocument = { + '@timestamp': '2018-01-01T10:11:12.000Z', + 'destination.address': '127.0.0.1', + 'destination.domain': 'example.com', + 'destination.ip': '127.0.0.1', + 'destination.port': 80, + 'ecs.version': '1.0.0-beta2', + 'event.dataset': 'iis.access', + 'event.duration': 789000000, + 'event.module': 'iis', + 'fileset.name': 'access', + 'http.request.body.bytes': 456, + 'http.request.method': 'GET', + 'http.request.referrer': '-', + 'http.response.body.bytes': 123, + 'http.response.status_code': 200, + 'http.version': '1.1', + 'iis.access.cookie': '-', + 'iis.access.server_name': 'MACHINE-NAME', + 'iis.access.site_name': 'W3SVC1', + 'iis.access.sub_status': 0, + 'iis.access.win32_status': 0, + 'input.type': 'log', + 'log.offset': 1204, + 'service.type': 'iis', + 'source.address': '85.181.35.98', + 'source.geo.city_name': 'Berlin', + 'source.geo.continent_name': 'Europe', + 'source.geo.country_iso_code': 'DE', + 'source.geo.location.lat': 52.4908, + 'source.geo.location.lon': 13.3275, + 'source.geo.region_iso_code': 'DE-BE', + 'source.geo.region_name': 'Land Berlin', + 'source.ip': '85.181.35.98', + 'url.path': '/', + 'url.query': 'q=100', + 'user.name': '-', + 'user_agent.device.name': 'Other', + 'user_agent.name': 'Chrome', + 'user_agent.original': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36', + 'user_agent.os.full': 'Mac OS X 10.14.0', + 'user_agent.os.name': 'Mac OS X', + 'user_agent.os.version': '10.14.0', + 'user_agent.version': '70.0.3538', + }; + + expect(format(flattenedDocument)).toMatchInlineSnapshot(` +Array [ + Object { + "constant": "[", + }, + Object { + "field": "event.module", + "highlights": Array [], + "value": "iis", + }, + Object { + "constant": "][access] ", + }, + Object { + "field": "source.ip", + "highlights": Array [], + "value": "85.181.35.98", + }, + Object { + "constant": " ", + }, + Object { + "field": "user.name", + "highlights": Array [], + "value": "-", + }, + Object { + "constant": " \\"", + }, + Object { + "field": "http.request.method", + "highlights": Array [], + "value": "GET", + }, + Object { + "constant": " ", + }, + Object { + "field": "url.path", + "highlights": Array [], + "value": "/", + }, + Object { + "constant": "?", + }, + Object { + "field": "url.query", + "highlights": Array [], + "value": "q=100", + }, + Object { + "constant": " HTTP/", + }, + Object { + "field": "http.version", + "highlights": Array [], + "value": "1.1", + }, + Object { + "constant": "\\" ", + }, + Object { + "field": "http.response.status_code", + "highlights": Array [], + "value": "200", + }, + Object { + "constant": " ", + }, + Object { + "field": "http.response.body.bytes", + "highlights": Array [], + "value": "123", + }, +] +`); + }); + + test('iis 7.5 access log', () => { + const flattenedDocument = { + '@timestamp': '2018-08-28T18:24:25.000Z', + 'destination.address': '10.100.220.70', + 'destination.ip': '10.100.220.70', + 'destination.port': 80, + 'ecs.version': '1.0.0-beta2', + 'event.dataset': 'iis.access', + 'event.duration': 792000000, + 'event.module': 'iis', + 'fileset.name': 'access', + 'http.request.method': 'GET', + 'http.response.status_code': 404, + 'iis.access.sub_status': 4, + 'iis.access.win32_status': 2, + 'input.type': 'log', + 'log.offset': 244, + 'service.type': 'iis', + 'source.address': '10.100.118.31', + 'source.ip': '10.100.118.31', + 'url.path': '/', + 'url.query': 'q=100', + 'user.name': '-', + 'user_agent.device.name': 'Other', + 'user_agent.name': 'IE', + 'user_agent.original': + 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR[ 2.0.50727](tel: 2050727); .NET CLR 3.0.30729)', + 'user_agent.os.name': 'Windows 8.1', + 'user_agent.version': '7.0', + }; + + expect(format(flattenedDocument)).toMatchInlineSnapshot(` +Array [ + Object { + "constant": "[", + }, + Object { + "field": "event.module", + "highlights": Array [], + "value": "iis", + }, + Object { + "constant": "][access] ", + }, + Object { + "field": "source.ip", + "highlights": Array [], + "value": "10.100.118.31", + }, + Object { + "constant": " ", + }, + Object { + "field": "user.name", + "highlights": Array [], + "value": "-", + }, + Object { + "constant": " \\"", + }, + Object { + "field": "http.request.method", + "highlights": Array [], + "value": "GET", + }, + Object { + "constant": " ", + }, + Object { + "field": "url.path", + "highlights": Array [], + "value": "/", + }, + Object { + "constant": "?", + }, + Object { + "field": "url.query", + "highlights": Array [], + "value": "q=100", + }, + Object { + "constant": " HTTP/", + }, + Object { + "field": "http.version", + "highlights": Array [], + "value": "undefined", + }, + Object { + "constant": "\\" ", + }, + Object { + "field": "http.response.status_code", + "highlights": Array [], + "value": "404", + }, + Object { + "constant": " ", + }, + Object { + "field": "http.response.body.bytes", + "highlights": Array [], + "value": "undefined", + }, +] +`); + }); + + test('iis error log', () => { + const flattenedDocument = { + '@timestamp': '2018-01-01T08:09:10.000Z', + 'destination.address': '172.31.77.6', + 'destination.ip': '172.31.77.6', + 'destination.port': 80, + 'ecs.version': '1.0.0-beta2', + 'event.dataset': 'iis.error', + 'event.module': 'iis', + 'fileset.name': 'error', + 'http.request.method': 'GET', + 'http.response.status_code': 503, + 'http.version': '1.1', + 'iis.error.queue_name': '-', + 'iis.error.reason_phrase': 'ConnLimit', + 'input.type': 'log', + 'log.offset': 186, + 'service.type': 'iis', + 'source.address': '172.31.77.6', + 'source.ip': '172.31.77.6', + 'source.port': 2094, + 'url.original': '/qos/1kbfile.txt', + }; + + expect(format(flattenedDocument)).toMatchInlineSnapshot(` +Array [ + Object { + "constant": "[iis][error] ", + }, + Object { + "field": "source.ip", + "highlights": Array [], + "value": "172.31.77.6", + }, + Object { + "constant": " ", + }, + Object { + "field": "iis.error.reason_phrase", + "highlights": Array [], + "value": "ConnLimit", + }, +] +`); + }); + }); + describe('in pre-ECS format', () => { test('iis access log', () => { const flattenedDocument = { @@ -52,7 +335,7 @@ describe('Filebeat Rules', () => { expect(format(flattenedDocument)).toMatchInlineSnapshot(` Array [ Object { - "constant": "[IIS][access] ", + "constant": "[iis][access] ", }, Object { "field": "iis.access.remote_ip", @@ -142,7 +425,7 @@ Array [ expect(format(flattenedDocument)).toMatchInlineSnapshot(` Array [ Object { - "constant": "[IIS][access] ", + "constant": "[iis][access] ", }, Object { "field": "iis.access.remote_ip", @@ -225,7 +508,7 @@ Array [ expect(format(flattenedDocument)).toMatchInlineSnapshot(` Array [ Object { - "constant": "[IIS][error] ", + "constant": "[iis][error] ", }, Object { "field": "iis.error.remote_ip", diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_iis.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_iis.ts index e8d447349e1f..ea3485440bb7 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_iis.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_iis.ts @@ -12,7 +12,7 @@ export const filebeatIisRules = [ }, format: [ { - constant: '[IIS][access] ', + constant: '[iis][access] ', }, { field: 'iis.access.remote_ip', @@ -62,7 +62,7 @@ export const filebeatIisRules = [ }, format: [ { - constant: '[IIS][error] ', + constant: '[iis][error] ', }, { field: 'iis.error.remote_ip', @@ -99,6 +99,26 @@ export const filebeatIisRules = [ }, ], }, + { + // ECS + when: { + exists: ['ecs.version', 'iis.error.reason_phrase'], + }, + format: [ + { + constant: '[iis][error] ', + }, + { + field: 'source.ip', + }, + { + constant: ' ', + }, + { + field: 'iis.error.reason_phrase', + }, + ], + }, { // pre-ECS when: { @@ -106,7 +126,7 @@ export const filebeatIisRules = [ }, format: [ { - constant: '[IIS][error] ', + constant: '[iis][error] ', }, { field: 'iis.error.remote_ip', diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_kafka.test.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_kafka.test.ts new file mode 100644 index 000000000000..0959091c4df5 --- /dev/null +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_kafka.test.ts @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { builtinRules } from '.'; +import { compileFormattingRules } from '../message'; + +const { format } = compileFormattingRules(builtinRules); + +describe('Filebeat Rules', () => { + describe('in ECS format', () => { + test('kafka log', () => { + const flattenedDocument = { + '@timestamp': '2017-08-04T10:48:21.063Z', + 'ecs.version': '1.0.0-beta2', + 'event.dataset': 'kafka.log', + 'event.module': 'kafka', + 'fileset.name': 'log', + 'input.type': 'log', + 'kafka.log.class': 'kafka.controller.KafkaController', + 'kafka.log.component': 'Controller 0', + 'log.level': 'INFO', + 'log.offset': 131, + message: '0 successfully elected as the controller', + 'service.type': 'kafka', + }; + + expect(format(flattenedDocument)).toMatchInlineSnapshot(` +Array [ + Object { + "constant": "[", + }, + Object { + "field": "event.dataset", + "highlights": Array [], + "value": "kafka.log", + }, + Object { + "constant": "][", + }, + Object { + "field": "log.level", + "highlights": Array [], + "value": "INFO", + }, + Object { + "constant": "] ", + }, + Object { + "field": "message", + "highlights": Array [], + "value": "0 successfully elected as the controller", + }, +] +`); + }); + }); +}); diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_logstash.test.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_logstash.test.ts index fc438d323b57..5be7c61cecb2 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_logstash.test.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_logstash.test.ts @@ -4,12 +4,106 @@ * you may not use this file except in compliance with the Elastic License. */ +import { builtinRules } from '.'; import { compileFormattingRules } from '../message'; -import { filebeatLogstashRules } from './filebeat_logstash'; -const { format } = compileFormattingRules(filebeatLogstashRules); +const { format } = compileFormattingRules(builtinRules); describe('Filebeat Rules', () => { + describe('in ECS format', () => { + test('logstash log', () => { + const flattenedDocument = { + '@timestamp': '2017-10-23T14:20:12.046Z', + 'ecs.version': '1.0.0-beta2', + 'event.dataset': 'logstash.log', + 'event.module': 'logstash', + 'fileset.name': 'log', + 'input.type': 'log', + 'log.level': 'INFO', + 'log.offset': 0, + 'logstash.log.module': 'logstash.modules.scaffold', + message: + 'Initializing module {:module_name=>"fb_apache", :directory=>"/usr/share/logstash/modules/fb_apache/configuration"}', + 'service.type': 'logstash', + }; + + expect(format(flattenedDocument)).toMatchInlineSnapshot(` +Array [ + Object { + "constant": "[", + }, + Object { + "field": "event.dataset", + "highlights": Array [], + "value": "logstash.log", + }, + Object { + "constant": "][", + }, + Object { + "field": "log.level", + "highlights": Array [], + "value": "INFO", + }, + Object { + "constant": "] ", + }, + Object { + "field": "message", + "highlights": Array [], + "value": "Initializing module {:module_name=>\\"fb_apache\\", :directory=>\\"/usr/share/logstash/modules/fb_apache/configuration\\"}", + }, +] +`); + }); + + test('logstash slowlog', () => { + const flattenedDocument = { + '@timestamp': '2017-10-30T09:57:58.243Z', + 'ecs.version': '1.0.0-beta2', + 'event.dataset': 'logstash.slowlog', + 'event.duration': 3027675106, + 'event.module': 'logstash', + 'fileset.name': 'slowlog', + 'input.type': 'log', + 'log.level': 'WARN', + 'log.offset': 0, + 'logstash.slowlog': { + event: + '"{\\"@version\\":\\"1\\",\\"@timestamp\\":\\"2017-10-30T13:57:55.130Z\\",\\"host\\":\\"sashimi\\",\\"sequence\\":0,\\"message\\":\\"Hello world!\\"}"', + module: 'slowlog.logstash.filters.sleep', + plugin_name: 'sleep', + plugin_params: + '{"time"=>3, "id"=>"e4e12a4e3082615c5427079bf4250dbfa338ebac10f8ea9912d7b98a14f56b8c"}', + plugin_type: 'filters', + took_in_millis: 3027, + }, + 'service.type': 'logstash', + }; + + expect(format(flattenedDocument)).toMatchInlineSnapshot(` +Array [ + Object { + "constant": "[Logstash][", + }, + Object { + "field": "log.level", + "highlights": Array [], + "value": "WARN", + }, + Object { + "constant": "] ", + }, + Object { + "field": "logstash.slowlog", + "highlights": Array [], + "value": "{\\"event\\":\\"\\\\\\"{\\\\\\\\\\\\\\"@version\\\\\\\\\\\\\\":\\\\\\\\\\\\\\"1\\\\\\\\\\\\\\",\\\\\\\\\\\\\\"@timestamp\\\\\\\\\\\\\\":\\\\\\\\\\\\\\"2017-10-30T13:57:55.130Z\\\\\\\\\\\\\\",\\\\\\\\\\\\\\"host\\\\\\\\\\\\\\":\\\\\\\\\\\\\\"sashimi\\\\\\\\\\\\\\",\\\\\\\\\\\\\\"sequence\\\\\\\\\\\\\\":0,\\\\\\\\\\\\\\"message\\\\\\\\\\\\\\":\\\\\\\\\\\\\\"Hello world!\\\\\\\\\\\\\\"}\\\\\\"\\",\\"module\\":\\"slowlog.logstash.filters.sleep\\",\\"plugin_name\\":\\"sleep\\",\\"plugin_params\\":\\"{\\\\\\"time\\\\\\"=>3, \\\\\\"id\\\\\\"=>\\\\\\"e4e12a4e3082615c5427079bf4250dbfa338ebac10f8ea9912d7b98a14f56b8c\\\\\\"}\\",\\"plugin_type\\":\\"filters\\",\\"took_in_millis\\":3027}", + }, +] +`); + }); + }); + describe('in pre-ECS format', () => { test('logstash log', () => { const flattenedDocument = { diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_logstash.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_logstash.ts index 6e0c26cd6802..39b2058ca7cd 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_logstash.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_logstash.ts @@ -31,6 +31,26 @@ export const filebeatLogstashRules = [ }, ], }, + { + // ECS + when: { + exists: ['ecs.version', 'logstash.slowlog'], + }, + format: [ + { + constant: '[Logstash][', + }, + { + field: 'log.level', + }, + { + constant: '] ', + }, + { + field: 'logstash.slowlog', + }, + ], + }, { // pre-ECS when: { diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mysql.test.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mysql.test.ts index d4576c6d2f67..230118697758 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mysql.test.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mysql.test.ts @@ -4,82 +4,216 @@ * you may not use this file except in compliance with the Elastic License. */ +import { builtinRules } from '.'; import { compileFormattingRules } from '../message'; -import { filebeatMySQLRules } from './filebeat_mysql'; -const { format } = compileFormattingRules(filebeatMySQLRules); +const { format } = compileFormattingRules(builtinRules); describe('Filebeat Rules', () => { - test('mysql error log', () => { - const errorDoc = { - 'mysql.error.message': - "Access denied for user 'petclinicdd'@'47.153.152.234' (using password: YES)", - }; - const message = format(errorDoc); - expect(message).toEqual([ - { - constant: '[MySQL][error] ', - }, - { - field: 'mysql.error.message', - highlights: [], - value: "Access denied for user 'petclinicdd'@'47.153.152.234' (using password: YES)", - }, - ]); + describe('in ECS format', () => { + test('mysql error log', () => { + const flattenedDocument = { + '@timestamp': '2016-12-09T12:08:33.335Z', + 'ecs.version': '1.0.0-beta2', + 'event.dataset': 'mysql.error', + 'event.module': 'mysql', + 'fileset.name': 'error', + 'input.type': 'log', + 'log.level': 'Warning', + 'log.offset': 92, + message: + 'TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).', + 'mysql.thread_id': 0, + 'service.type': 'mysql', + }; + + expect(format(flattenedDocument)).toMatchInlineSnapshot(` +Array [ + Object { + "constant": "[", + }, + Object { + "field": "event.dataset", + "highlights": Array [], + "value": "mysql.error", + }, + Object { + "constant": "][", + }, + Object { + "field": "log.level", + "highlights": Array [], + "value": "Warning", + }, + Object { + "constant": "] ", + }, + Object { + "field": "message", + "highlights": Array [], + "value": "TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).", + }, +] +`); + }); + + test('mysql slowlog', () => { + const flattenedDocument = { + '@timestamp': '2018-08-07T08:27:47.000Z', + 'ecs.version': '1.0.0-beta2', + 'event.dataset': 'mysql.slowlog', + 'event.duration': 4071491000, + 'event.module': 'mysql', + 'fileset.name': 'slowlog', + 'input.type': 'log', + 'log.flags': ['multiline'], + 'log.offset': 526, + 'mysql.slowlog.current_user': 'appuser', + 'mysql.slowlog.lock_time.sec': 0.000212, + 'mysql.slowlog.query': + 'SELECT mcu.mcu_guid, mcu.cus_guid, mcu.mcu_url, mcu.mcu_crawlelements, mcu.mcu_order, GROUP_CONCAT(mca.mca_guid SEPARATOR ";") as mca_guid\n FROM kat_mailcustomerurl mcu, kat_customer cus, kat_mailcampaign mca\n WHERE cus.cus_guid = mcu.cus_guid\n AND cus.pro_code = \'CYB\'\n AND cus.cus_offline = 0\n AND mca.cus_guid = cus.cus_guid\n AND (mcu.mcu_date IS NULL OR mcu.mcu_date < CURDATE())\n AND mcu.mcu_crawlelements IS NOT NULL\n GROUP BY mcu.mcu_guid\n ORDER BY mcu.mcu_order ASC\n LIMIT 1000;', + 'mysql.slowlog.rows_examined': 1489615, + 'mysql.slowlog.rows_sent': 1000, + 'mysql.thread_id': 10997316, + 'service.type': 'mysql', + 'source.domain': 'apphost', + 'source.ip': '1.1.1.1', + 'user.name': 'appuser', + }; + + expect(format(flattenedDocument)).toMatchInlineSnapshot(` +Array [ + Object { + "constant": "[MySQL][slowlog] ", + }, + Object { + "field": "user.name", + "highlights": Array [], + "value": "appuser", + }, + Object { + "constant": "@", + }, + Object { + "field": "source.domain", + "highlights": Array [], + "value": "apphost", + }, + Object { + "constant": " [", + }, + Object { + "field": "source.ip", + "highlights": Array [], + "value": "1.1.1.1", + }, + Object { + "constant": "] ", + }, + Object { + "constant": " - ", + }, + Object { + "field": "event.duration", + "highlights": Array [], + "value": "4071491000", + }, + Object { + "constant": " ns - ", + }, + Object { + "field": "mysql.slowlog.query", + "highlights": Array [], + "value": "SELECT mcu.mcu_guid, mcu.cus_guid, mcu.mcu_url, mcu.mcu_crawlelements, mcu.mcu_order, GROUP_CONCAT(mca.mca_guid SEPARATOR \\";\\") as mca_guid + FROM kat_mailcustomerurl mcu, kat_customer cus, kat_mailcampaign mca + WHERE cus.cus_guid = mcu.cus_guid + AND cus.pro_code = 'CYB' + AND cus.cus_offline = 0 + AND mca.cus_guid = cus.cus_guid + AND (mcu.mcu_date IS NULL OR mcu.mcu_date < CURDATE()) + AND mcu.mcu_crawlelements IS NOT NULL + GROUP BY mcu.mcu_guid + ORDER BY mcu.mcu_order ASC + LIMIT 1000;", + }, +] +`); + }); }); - test('mysql slow log', () => { - const errorDoc = { - 'mysql.slowlog.query': 'select * from hosts', - 'mysql.slowlog.query_time.sec': 5, - 'mysql.slowlog.user': 'admin', - 'mysql.slowlog.ip': '192.168.1.42', - 'mysql.slowlog.host': 'webserver-01', - }; - const message = format(errorDoc); - expect(message).toEqual([ - { - constant: '[MySQL][slowlog] ', - }, - { - field: 'mysql.slowlog.user', - highlights: [], - value: 'admin', - }, - { - constant: '@', - }, - { - field: 'mysql.slowlog.host', - highlights: [], - value: 'webserver-01', - }, - { - constant: ' [', - }, - { - field: 'mysql.slowlog.ip', - highlights: [], - value: '192.168.1.42', - }, - { - constant: '] ', - }, - { - constant: ' - ', - }, - { - field: 'mysql.slowlog.query_time.sec', - highlights: [], - value: '5', - }, - { - constant: 'sec - ', - }, - { - field: 'mysql.slowlog.query', - highlights: [], - value: 'select * from hosts', - }, - ]); + + describe('in pre-ECS format', () => { + test('mysql error log', () => { + const errorDoc = { + 'mysql.error.message': + "Access denied for user 'petclinicdd'@'47.153.152.234' (using password: YES)", + }; + const message = format(errorDoc); + expect(message).toEqual([ + { + constant: '[MySQL][error] ', + }, + { + field: 'mysql.error.message', + highlights: [], + value: "Access denied for user 'petclinicdd'@'47.153.152.234' (using password: YES)", + }, + ]); + }); + + test('mysql slow log', () => { + const errorDoc = { + 'mysql.slowlog.query': 'select * from hosts', + 'mysql.slowlog.query_time.sec': 5, + 'mysql.slowlog.user': 'admin', + 'mysql.slowlog.ip': '192.168.1.42', + 'mysql.slowlog.host': 'webserver-01', + }; + const message = format(errorDoc); + expect(message).toEqual([ + { + constant: '[MySQL][slowlog] ', + }, + { + field: 'mysql.slowlog.user', + highlights: [], + value: 'admin', + }, + { + constant: '@', + }, + { + field: 'mysql.slowlog.host', + highlights: [], + value: 'webserver-01', + }, + { + constant: ' [', + }, + { + field: 'mysql.slowlog.ip', + highlights: [], + value: '192.168.1.42', + }, + { + constant: '] ', + }, + { + constant: ' - ', + }, + { + field: 'mysql.slowlog.query_time.sec', + highlights: [], + value: '5', + }, + { + constant: ' s - ', + }, + { + field: 'mysql.slowlog.query', + highlights: [], + value: 'select * from hosts', + }, + ]); + }); }); }); diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mysql.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mysql.ts index 294a9a4d0752..e90977f9bf8f 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mysql.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_mysql.ts @@ -6,6 +6,7 @@ export const filebeatMySQLRules = [ { + // pre-ECS when: { exists: ['mysql.error.message'], }, @@ -19,6 +20,48 @@ export const filebeatMySQLRules = [ ], }, { + // ECS + when: { + exists: ['ecs.version', 'mysql.slowlog.query'], + }, + format: [ + { + constant: '[MySQL][slowlog] ', + }, + { + field: 'user.name', + }, + { + constant: '@', + }, + { + field: 'source.domain', + }, + { + constant: ' [', + }, + { + field: 'source.ip', + }, + { + constant: '] ', + }, + { + constant: ' - ', + }, + { + field: 'event.duration', + }, + { + constant: ' ns - ', + }, + { + field: 'mysql.slowlog.query', + }, + ], + }, + { + // pre-ECS when: { exists: ['mysql.slowlog.user', 'mysql.slowlog.query_time.sec', 'mysql.slowlog.query'], }, @@ -51,7 +94,7 @@ export const filebeatMySQLRules = [ field: 'mysql.slowlog.query_time.sec', }, { - constant: 'sec - ', + constant: ' s - ', }, { field: 'mysql.slowlog.query', diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_nginx.test.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_nginx.test.ts index 22b837ec31d0..8565503e09a0 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_nginx.test.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_nginx.test.ts @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ +import { builtinRules } from '.'; import { compileFormattingRules } from '../message'; -import { filebeatNginxRules } from './filebeat_nginx'; -const { format } = compileFormattingRules(filebeatNginxRules); +const { format } = compileFormattingRules(builtinRules); describe('Filebeat Rules', () => { describe('in ECS format', () => { @@ -43,7 +43,15 @@ describe('Filebeat Rules', () => { expect(format(flattenedDocument)).toMatchInlineSnapshot(` Array [ Object { - "constant": "[Nginx][access] ", + "constant": "[", + }, + Object { + "field": "event.module", + "highlights": Array [], + "value": "nginx", + }, + Object { + "constant": "][access] ", }, Object { "field": "source.ip", @@ -123,7 +131,7 @@ Array [ expect(format(flattenedDocument)).toMatchInlineSnapshot(` Array [ Object { - "constant": "[Nginx]", + "constant": "[nginx]", }, Object { "constant": "[", @@ -162,7 +170,7 @@ Array [ expect(format(flattenedDocument)).toMatchInlineSnapshot(` Array [ Object { - "constant": "[Nginx][access] ", + "constant": "[nginx][access] ", }, Object { "field": "nginx.access.remote_ip", @@ -231,7 +239,7 @@ Array [ expect(format(flattenedDocument)).toMatchInlineSnapshot(` Array [ Object { - "constant": "[Nginx]", + "constant": "[nginx]", }, Object { "constant": "[", diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_nginx.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_nginx.ts index c86ba75740b2..0fd70dc25bb8 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_nginx.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_nginx.ts @@ -5,66 +5,14 @@ */ export const filebeatNginxRules = [ - { - // ECS - when: { - values: { - 'event.dataset': 'nginx.access', - }, - }, - format: [ - { - constant: '[Nginx][access] ', - }, - { - field: 'source.ip', - }, - { - constant: ' ', - }, - { - field: 'user.name', - }, - { - constant: ' "', - }, - { - field: 'http.request.method', - }, - { - constant: ' ', - }, - { - field: 'url.original', - }, - { - constant: ' HTTP/', - }, - { - field: 'http.version', - }, - { - constant: '" ', - }, - { - field: 'http.response.status_code', - }, - { - constant: ' ', - }, - { - field: 'http.response.body.bytes', - }, - ], - }, { // pre-ECS when: { - exists: ['nginx.access'], + exists: ['nginx.access.method'], }, format: [ { - constant: '[Nginx][access] ', + constant: '[nginx][access] ', }, { field: 'nginx.access.remote_ip', @@ -116,7 +64,7 @@ export const filebeatNginxRules = [ }, format: [ { - constant: '[Nginx]', + constant: '[nginx]', }, { constant: '[', @@ -139,7 +87,7 @@ export const filebeatNginxRules = [ }, format: [ { - constant: '[Nginx]', + constant: '[nginx]', }, { constant: '[', diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_traefik.test.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_traefik.test.ts index c8a13b54dfae..2ffb15457b7c 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_traefik.test.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_traefik.test.ts @@ -54,7 +54,7 @@ describe('Filebeat Rules', () => { expect(format(flattenedDocument)).toMatchInlineSnapshot(` Array [ Object { - "constant": "[Traefik][access] ", + "constant": "[traefik][access] ", }, Object { "field": "traefik.access.remote_ip", diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_traefik.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_traefik.ts index 9b0244900364..e62c688b9c22 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_traefik.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/filebeat_traefik.ts @@ -12,7 +12,7 @@ export const filebeatTraefikRules = [ }, format: [ { - constant: '[Traefik][access] ', + constant: '[traefik][access] ', }, { field: 'traefik.access.remote_ip', diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/generic.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/generic.ts index bd0e51d5c8d3..3ddc8d67c9a2 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/generic.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/generic.ts @@ -5,6 +5,50 @@ */ export const genericRules = [ + { + when: { + exists: ['event.dataset', 'log.level', 'message'], + }, + format: [ + { + constant: '[', + }, + { + field: 'event.dataset', + }, + { + constant: '][', + }, + { + field: 'log.level', + }, + { + constant: '] ', + }, + { + field: 'message', + }, + ], + }, + { + when: { + exists: ['log.level', 'message'], + }, + format: [ + { + constant: '[', + }, + { + field: 'log.level', + }, + { + constant: '] ', + }, + { + field: 'message', + }, + ], + }, { when: { exists: ['message'], @@ -25,4 +69,33 @@ export const genericRules = [ }, ], }, + { + when: { + exists: ['event.dataset', 'log.original'], + }, + format: [ + { + constant: '[', + }, + { + field: 'event.dataset', + }, + { + constant: '] ', + }, + { + field: 'log.original', + }, + ], + }, + { + when: { + exists: ['log.original'], + }, + format: [ + { + field: 'log.original', + }, + ], + }, ]; diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/generic_webserver.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/generic_webserver.ts new file mode 100644 index 000000000000..50f38ad0515b --- /dev/null +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/generic_webserver.ts @@ -0,0 +1,116 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +const commonPrefixFields = [ + { constant: '[' }, + { field: 'event.module' }, + { constant: '][access] ' }, +]; + +export const genericWebserverRules = [ + { + // ECS with parsed url + when: { + exists: ['ecs.version', 'http.response.status_code', 'url.path'], + }, + format: [ + ...commonPrefixFields, + { + field: 'source.ip', + }, + { + constant: ' ', + }, + { + field: 'user.name', + }, + { + constant: ' "', + }, + { + field: 'http.request.method', + }, + { + constant: ' ', + }, + { + field: 'url.path', + }, + { + constant: '?', + }, + { + field: 'url.query', + }, + { + constant: ' HTTP/', + }, + { + field: 'http.version', + }, + { + constant: '" ', + }, + { + field: 'http.response.status_code', + }, + { + constant: ' ', + }, + { + field: 'http.response.body.bytes', + }, + ], + }, + { + // ECS with original url + when: { + exists: ['ecs.version', 'http.response.status_code'], + }, + format: [ + ...commonPrefixFields, + { + field: 'source.ip', + }, + { + constant: ' ', + }, + { + field: 'user.name', + }, + { + constant: ' "', + }, + { + field: 'http.request.method', + }, + { + constant: ' ', + }, + { + field: 'url.original', + }, + { + constant: ' HTTP/', + }, + { + field: 'http.version', + }, + { + constant: '" ', + }, + { + field: 'http.response.status_code', + }, + { + constant: ' ', + }, + { + field: 'http.response.body.bytes', + }, + ], + }, +]; diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/helpers.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/helpers.ts new file mode 100644 index 000000000000..9a6fa30e17e8 --- /dev/null +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/helpers.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export const labelField = (label: string, field: string) => [ + { constant: ' ' }, + { constant: label }, + { constant: '=' }, + { field }, +]; diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/index.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/index.ts index cc0cf96cf1ea..cc254d554837 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/index.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/builtin_rules/index.ts @@ -19,6 +19,7 @@ import { filebeatSystemRules } from './filebeat_system'; import { filebeatTraefikRules } from './filebeat_traefik'; import { genericRules } from './generic'; +import { genericWebserverRules } from './generic_webserver'; export const builtinRules = [ ...filebeatApache2Rules, @@ -34,6 +35,7 @@ export const builtinRules = [ ...filebeatMongodbRules, ...filebeatOsqueryRules, ...filebeatTraefikRules, + ...genericWebserverRules, ...genericRules, { when: {