Skip to content

Commit f7b8d38

Browse files
author
Gareth Jones
committed
chore: copied from log4js core
1 parent 1911f75 commit f7b8d38

File tree

8 files changed

+7494
-0
lines changed

8 files changed

+7494
-0
lines changed

.eslintrc

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"root": true,
3+
"extends": "airbnb-base",
4+
"rules": {
5+
"comma-dangle": 0,
6+
"indent": 2,
7+
"object-shorthand": 0,
8+
"func-names": 0,
9+
"max-len": [1, 120, 2],
10+
"no-use-before-define": ["warn"],
11+
"no-param-reassign": 0,
12+
"strict": 0,
13+
"import/no-extraneous-dependencies": 1,
14+
"prefer-spread": 0,
15+
"prefer-rest-params": 0,
16+
"prefer-destructuring": 0
17+
},
18+
"parserOptions": {
19+
"ecmaVersion": 6
20+
}
21+
}

.travis.yml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
language: node_js
2+
dist: trusty
3+
sudo: false
4+
node_js:
5+
- "10"
6+
- "8"
7+
- "6"
8+
after_success:
9+
- npm run codecov

README.md

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# logstash Appender (HTTP) for log4js-node
2+
3+
The logstash appenders for [log4js](https://log4js-node.github.io/log4js-node) send NDJSON formatted log events to [logstash](https://www.elastic.co/products/logstash) receivers. This appender uses HTTP to send the events (there is another logstash appender that uses [UDP](https://github.com/log4js-node/logstashUDP)).
4+
5+
```bash
6+
npm install log4js @log4js-node/logstashHTTP
7+
```
8+
9+
## Configuration
10+
11+
* `type` - `@log4js-node/logstashHTTP`
12+
* `url` - `string` - logFaces receiver servlet URL
13+
* `application` - `string` (optional) - used to identify your application's logs
14+
* `logChannel` - `string` (optional) - also used to identify your application's logs [but in a more specific way]
15+
* `logType` - `string` (optional) - used for the `type` field in the logstash data
16+
* `timeout` - `integer` (optional, defaults to 5000ms) - the timeout for the HTTP request.
17+
18+
This appender will also pick up Logger context values from the events, and add them as `p_` values in the logFaces event. See the example below for more details.
19+
20+
# Example (default config)
21+
22+
```javascript
23+
log4js.configure({
24+
appenders: {
25+
logstash: { type: '@log4js-node/logstashHTTP', url: 'http://localhost:9200/_bulk', application: 'logstash-log4js', logType: 'application', logChannel: 'node' }
26+
},
27+
categories: {
28+
default: { appenders: [ 'logstash' ], level: 'info' }
29+
}
30+
});
31+
32+
const logger = log4js.getLogger();
33+
logger.addContext('requestId', '123');
34+
logger.info('some interesting log message');
35+
logger.error('something has gone wrong');
36+
```
37+
This example will result in two log events being sent to your `localhost:9200`. Both events will have a `context.requestId` property with a value of `123`.

lib/index.js

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
'use strict';
2+
3+
/**
4+
* logstashHTTP appender sends JSON formatted log events to logstashHTTP receivers.
5+
*/
6+
const util = require('util');
7+
const axios = require('axios');
8+
9+
function wrapErrorsWithInspect(items) {
10+
return items.map((item) => {
11+
if ((item instanceof Error) && item.stack) {
12+
return {
13+
inspect: function () {
14+
return `${util.format(item)}\n${item.stack}`;
15+
}
16+
};
17+
}
18+
19+
return item;
20+
});
21+
}
22+
23+
function format(logData) {
24+
const data = Array.isArray(logData)
25+
? logData
26+
: Array.prototype.slice.call(arguments);
27+
return util.format.apply(util, wrapErrorsWithInspect(data));
28+
}
29+
30+
/**
31+
*
32+
* For HTTP (browsers or node.js) use the following configuration params:
33+
* {
34+
* "type": "logstashHTTP", // must be present for instantiation
35+
* "application": "logstash-test", // name of the application
36+
* "logType": "application", // type of the application
37+
* "logChannel": "test", // channel of the application
38+
* "url": "http://lfs-server/_bulk", // logstash receiver servlet URL
39+
* }
40+
*/
41+
function logstashHTTPAppender(config) {
42+
const sender = axios.create({
43+
baseURL: config.url,
44+
timeout: config.timeout || 5000,
45+
headers: { 'Content-Type': 'application/x-ndjson' },
46+
withCredentials: true,
47+
});
48+
49+
return function log(event) {
50+
const logstashEvent = [
51+
{
52+
index: {
53+
_index: config.application,
54+
_type: config.logType,
55+
},
56+
},
57+
{
58+
message: format(event.data),
59+
context: event.context,
60+
level: event.level.level / 100,
61+
level_name: event.level.levelStr,
62+
channel: config.logChannel,
63+
datetime: (new Date(event.startTime)).toISOString(),
64+
extra: {},
65+
},
66+
];
67+
const logstashJSON = `${JSON.stringify(logstashEvent[0])}\n${JSON.stringify(logstashEvent[1])}\n`;
68+
69+
// send to server
70+
sender.post('', logstashJSON)
71+
.catch((error) => {
72+
if (error.response) {
73+
console.error(`log4js.logstashHTTP Appender error posting to ${config.url}: ${error.response.status} - ${error.response.data}`);
74+
return;
75+
}
76+
console.error(`log4js.logstashHTTP Appender error: ${error.message}`);
77+
});
78+
};
79+
}
80+
81+
function configure(config) {
82+
return logstashHTTPAppender(config);
83+
}
84+
85+
module.exports.configure = configure;

0 commit comments

Comments
 (0)