Skip to content

Commit eb0dadf

Browse files
authored
Merge pull request gistia#2 from gistia/fcoury/feat/transform-log-format
feat: allow using a transform file
2 parents f6c5d41 + 27898dc commit eb0dadf

File tree

8 files changed

+132
-3
lines changed

8 files changed

+132
-3
lines changed

README.md

+37
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,43 @@ npm install --global json-log-viewer
4141
jv application.log.2017-01-01 --sort -timestamp
4242
```
4343

44+
### Configuration
45+
46+
The default expected log format include fields `timestamp`, `level` and `message`. If the log file you're trying to parse doesn't include those fields, you can create a config file on your HOME path called `.json-log-viewer`.
47+
48+
For example, if your log lines look like this:
49+
50+
```json
51+
{
52+
"message":
53+
"Matched route \"**_heartbeat_check\" (parameters: \"_controller\": \"**\\Controller\\**Controller::heartbeatCheckAction\", \"_route\": \"**_heartbeat_check\")",
54+
"context": [],
55+
"level": 200,
56+
"level_name": "INFO",
57+
"channel": "request",
58+
"datetime": {
59+
"date": "2017-12-06 09:23:42.253060",
60+
"timezone_type": 3,
61+
"timezone": "Europe/Berlin"
62+
},
63+
"extra": []
64+
}
65+
```
66+
67+
You can create a mapping configuration like this:
68+
69+
```ini
70+
[transform]
71+
level=level_name
72+
timestamp=datetime.date
73+
message=message
74+
extra=$
75+
```
76+
77+
This way the messages will properly be displayed. The `$` has a special meaning: it tells the the old object should be included on the `extra` key on the resulting JSON. The result will look like this:
78+
79+
![transform](transform.png)
80+
4481
## Screenshots
4582

4683
__Details view__

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"dependencies": {
1616
"blessed": "0.1.81",
1717
"blessed-contrib": "4.8.5",
18+
"ini": "1.3.5",
1819
"lodash": "4.17.4",
1920
"minimist": "1.2.0"
2021
},

src/log.js

+43-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,50 @@
11
const fs = require('fs');
2+
const os = require('os');
3+
const path = require('path');
4+
const ini = require('ini');
25
const _ = require('lodash');
36

7+
let _transform = 'unloaded';
8+
9+
function loadTransform(_fs=fs) {
10+
if (_transform === 'unloaded') {
11+
const transformFile = path.join(os.homedir(), '.json-log-viewer');
12+
if (!_fs.existsSync(transformFile)) {
13+
return;
14+
}
15+
16+
const contents = _fs.readFileSync(transformFile, 'utf8');
17+
const { transform } = ini.parse(contents);
18+
if (!transform) {
19+
return;
20+
}
21+
22+
_transform = transform;
23+
}
24+
25+
return _transform;
26+
}
27+
28+
function transform(entry, _fs=fs) {
29+
const transform = loadTransform(_fs);
30+
if (!transform) {
31+
return entry;
32+
}
33+
34+
return Object.keys(transform).reduce((hash, key) => {
35+
const value = transform[key];
36+
if (value === '$') {
37+
hash[key] = _.cloneDeep(entry);
38+
} else {
39+
hash[key] = _.get(entry, value);
40+
}
41+
return hash;
42+
}, {});
43+
}
44+
445
function parse(line) {
546
try {
6-
return JSON.parse(line);
47+
return transform(JSON.parse(line));
748
} catch (e) {
849
return null;
950
}
@@ -20,4 +61,4 @@ function readLog(file, reader=fs) {
2061
});
2162
};
2263

23-
module.exports = { readLog };
64+
module.exports = { readLog, transform };

test/fixtures/monolog.log.json

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"message":
3+
"Matched route \"**_heartbeat_check\" (parameters: \"_controller\": \"**\\Controller\\**Controller::heartbeatCheckAction\", \"_route\": \"**_heartbeat_check\")",
4+
"context": [],
5+
"level": 200,
6+
"level_name": "INFO",
7+
"channel": "request",
8+
"datetime": {
9+
"date": "2017-12-06 09:23:42.253060",
10+
"timezone_type": 3,
11+
"timezone": "Europe/Berlin"
12+
},
13+
"extra": []
14+
}

test/fixtures/transform1.ini

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[transform]
2+
level=level_name
3+
timestamp=datetime.date
4+
message=message
5+
extra=$

test/log.test.js

+28-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const { loadFixture } = require('./support/fixtures');
2-
const { readLog } = require('../src/log');
2+
const { readLog, transform } = require('../src/log');
33

44
describe('readLog', () => {
55
let entries;
@@ -40,3 +40,30 @@ describe('readLog', () => {
4040
});
4141
});
4242
});
43+
44+
describe.only('transform', () => {
45+
let exists = false;
46+
let contents = null;
47+
48+
const fs = {
49+
existsSync: () => exists,
50+
readFileSync: () => contents,
51+
};
52+
53+
describe('when config doesn\'t exist', () => {
54+
it('returns the unmodified line', () => {
55+
expect(transform('something', fs)).to.eql('something');
56+
});
57+
});
58+
59+
describe('when config exists', () => {
60+
it('transforms the line', () => {
61+
exists = true;
62+
contents = loadFixture('transform1.ini');
63+
const logEntry = JSON.parse(loadFixture('monolog.log.json'));
64+
const entry = transform(logEntry, fs);
65+
expect(entry.timestamp).to.eql('2017-12-06 09:23:42.253060');
66+
expect(entry.level).to.eql('INFO');
67+
});
68+
});
69+
});

transform.png

475 KB
Loading

yarn.lock

+4
Original file line numberDiff line numberDiff line change
@@ -1516,6 +1516,10 @@ inherits@2, [email protected], inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, i
15161516
version "2.0.3"
15171517
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
15181518

1519+
1520+
version "1.3.5"
1521+
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
1522+
15191523
ini@~1.3.0:
15201524
version "1.3.4"
15211525
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e"

0 commit comments

Comments
 (0)