1 | 'use strict'
|
2 |
|
3 | const path = require('path')
|
4 | const spawn = require('child_process').spawn
|
5 | const test = require('tap').test
|
6 |
|
7 | const bin = require.resolve(path.join(__dirname, '..', 'bin.js'))
|
8 | const epoch = 1522431328992
|
9 | const logLine = '{"level":30,"time":1522431328992,"msg":"hello world","pid":42,"hostname":"foo"}\n'
|
10 |
|
11 | test('cli', (t) => {
|
12 | t.test('does basic reformatting', (t) => {
|
13 | t.plan(1)
|
14 | const env = { TERM: 'dumb' }
|
15 | const child = spawn(process.argv[0], [bin], { env })
|
16 | child.on('error', t.threw)
|
17 | child.stdout.on('data', (data) => {
|
18 | t.is(data.toString(), `[${epoch}] INFO (42 on foo): hello world\n`)
|
19 | })
|
20 | child.stdin.write(logLine)
|
21 | t.tearDown(() => child.kill())
|
22 | })
|
23 |
|
24 | t.test('flips epoch and level', (t) => {
|
25 | t.plan(1)
|
26 | const env = { TERM: 'dumb' }
|
27 | const child = spawn(process.argv[0], [bin, '-l'], { env })
|
28 | child.on('error', t.threw)
|
29 | child.stdout.on('data', (data) => {
|
30 | t.is(data.toString(), `INFO [${epoch}] (42 on foo): hello world\n`)
|
31 | })
|
32 | child.stdin.write(logLine)
|
33 | t.tearDown(() => child.kill())
|
34 | })
|
35 |
|
36 | t.test('translates time to default format', (t) => {
|
37 | t.plan(1)
|
38 | const env = { TERM: 'dumb' }
|
39 | const child = spawn(process.argv[0], [bin, '-t'], { env })
|
40 | child.on('error', t.threw)
|
41 | child.stdout.on('data', (data) => {
|
42 | t.is(data.toString(), '[2018-03-30 17:35:28.992 +0000] INFO (42 on foo): hello world\n')
|
43 | })
|
44 | child.stdin.write(logLine)
|
45 | t.tearDown(() => child.kill())
|
46 | })
|
47 |
|
48 | t.test('does search', (t) => {
|
49 | t.plan(1)
|
50 | const env = { TERM: 'dumb' }
|
51 | const child = spawn(process.argv[0], [bin, '-s', 'msg == `hello world`'], { env })
|
52 | child.on('error', t.threw)
|
53 | child.stdout.on('data', (data) => {
|
54 | t.is(data.toString(), `[${epoch}] INFO (42 on foo): hello world\n`)
|
55 | })
|
56 | child.stdin.write(logLine)
|
57 | t.tearDown(() => child.kill())
|
58 | })
|
59 |
|
60 | t.test('does search but finds only 1 out of 2', (t) => {
|
61 | t.plan(1)
|
62 | const env = { TERM: 'dumb' }
|
63 | const child = spawn(process.argv[0], [bin, '-s', 'msg == `hello world`'], { env })
|
64 | child.on('error', t.threw)
|
65 | child.stdout.on('data', (data) => {
|
66 | t.is(data.toString(), `[${epoch}] INFO (42 on foo): hello world\n`)
|
67 | })
|
68 | child.stdin.write(logLine.replace('hello world', 'hello universe'))
|
69 | child.stdin.write(logLine)
|
70 | t.tearDown(() => child.kill())
|
71 | })
|
72 |
|
73 | t.test('does ignore multiple keys', (t) => {
|
74 | t.plan(1)
|
75 | const env = { TERM: 'dumb' }
|
76 | const child = spawn(process.argv[0], [bin, '-i', 'pid,hostname'], { env })
|
77 | child.on('error', t.threw)
|
78 | child.stdout.on('data', (data) => {
|
79 | t.is(data.toString(), '[1522431328992] INFO: hello world\n')
|
80 | })
|
81 | child.stdin.write(logLine)
|
82 | t.tearDown(() => child.kill())
|
83 | })
|
84 |
|
85 | t.test('passes through stringified date as string', (t) => {
|
86 | t.plan(1)
|
87 | const env = { TERM: 'dumb' }
|
88 | const child = spawn(process.argv[0], [bin], { env })
|
89 | child.on('error', t.threw)
|
90 |
|
91 | const date = JSON.stringify(new Date(epoch))
|
92 |
|
93 | child.stdout.on('data', (data) => {
|
94 | t.is(data.toString(), date + '\n')
|
95 | })
|
96 |
|
97 | child.stdin.write(date)
|
98 | child.stdin.write('\n')
|
99 |
|
100 | t.tearDown(() => child.kill())
|
101 | })
|
102 |
|
103 | t.test('uses specified timestampKey', (t) => {
|
104 | t.plan(1)
|
105 | const env = { TERM: 'dumb' }
|
106 | const child = spawn(process.argv[0], [bin, '--timestampKey', '@timestamp'], { env })
|
107 | child.on('error', t.threw)
|
108 | child.stdout.on('data', (data) => {
|
109 | t.is(data.toString(), '[1522431328992] INFO: hello world\n')
|
110 | })
|
111 | const logLine = '{"level":30,"@timestamp":1522431328992,"msg":"hello world"}\n'
|
112 | child.stdin.write(logLine)
|
113 | t.tearDown(() => child.kill())
|
114 | })
|
115 |
|
116 | t.test('singleLine=true', (t) => {
|
117 | t.plan(1)
|
118 |
|
119 | const logLineWithExtra = JSON.stringify(Object.assign(JSON.parse(logLine), {
|
120 | extra: {
|
121 | foo: 'bar',
|
122 | number: 42
|
123 | }
|
124 | })) + '\n'
|
125 |
|
126 | const env = { TERM: 'dumb' }
|
127 | const child = spawn(process.argv[0], [bin, '--singleLine'], { env })
|
128 | child.on('error', t.threw)
|
129 | child.stdout.on('data', (data) => {
|
130 | t.is(data.toString(), `[${epoch}] INFO (42 on foo): hello world {"extra":{"foo":"bar","number":42}}\n`)
|
131 | })
|
132 | child.stdin.write(logLineWithExtra)
|
133 | t.tearDown(() => child.kill())
|
134 | })
|
135 |
|
136 | t.test('does ignore nested keys', (t) => {
|
137 | t.plan(1)
|
138 |
|
139 | const logLineNested = JSON.stringify(Object.assign(JSON.parse(logLine), {
|
140 | extra: {
|
141 | foo: 'bar',
|
142 | number: 42,
|
143 | nested: {
|
144 | foo2: 'bar2'
|
145 | }
|
146 | }
|
147 | })) + '\n'
|
148 |
|
149 | const env = { TERM: 'dumb' }
|
150 | const child = spawn(process.argv[0], [bin, '-S', '-i', 'extra.foo,extra.nested,extra.nested.miss'], { env })
|
151 | child.on('error', t.threw)
|
152 | child.stdout.on('data', (data) => {
|
153 | t.is(data.toString(), `[${epoch}] INFO (42 on foo): hello world {"extra":{"number":42}}\n`)
|
154 | })
|
155 | child.stdin.write(logLineNested)
|
156 | t.tearDown(() => child.kill())
|
157 | })
|
158 |
|
159 | t.end()
|
160 | })
|