[Logs UI] Fix some filebeat ECS message formats (#31120)

This commit is contained in:
Felix Stürmer 2019-02-21 18:24:19 +01:00 committed by GitHub
parent a6ed6a3b24
commit 3d7a6a19fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 1890 additions and 355 deletions

View file

@ -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",

View file

@ -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',

View file

@ -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' },
};
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',
},
};
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 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' },
]);
});
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 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 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 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.' },
]);
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.' },
]);
});
});
});

View file

@ -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'],
},

View file

@ -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': '<NOSRV>',
'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": "<NOSRV>",
},
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": " ",
},
]
`);
});

View file

@ -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,
],
},
];

View file

@ -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",

View file

@ -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',

View file

@ -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",
},
]
`);
});
});
});

View file

@ -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 = {

View file

@ -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: {

View file

@ -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',
},
]);
});
});
});

View file

@ -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',

View file

@ -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": "[",

View file

@ -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: '[',

View file

@ -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",

View file

@ -12,7 +12,7 @@ export const filebeatTraefikRules = [
},
format: [
{
constant: '[Traefik][access] ',
constant: '[traefik][access] ',
},
{
field: 'traefik.access.remote_ip',

View file

@ -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',
},
],
},
];

View file

@ -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',
},
],
},
];

View file

@ -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 },
];

View file

@ -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: {