|
1 | 1 | /** |
2 | 2 | * Licensed Materials - Property of IBM |
3 | | - * (c) Copyright IBM Corporation 2016, 2017. All Rights Reserved. |
| 3 | + * (c) Copyright IBM Corporation 2016, 2018. All Rights Reserved. |
4 | 4 | * |
5 | 5 | * Note to U.S. Government Users Restricted Rights: |
6 | 6 | * Use, duplication or disclosure restricted by GSA ADP Schedule |
7 | 7 | * Contract with IBM Corp. |
8 | 8 | */ |
| 9 | + |
9 | 10 | 'use strict'; |
10 | 11 |
|
11 | | -var log4js = require('log4js'), |
12 | | - util = require('util'), |
13 | | - logmetConnection = require('./lib/logmet-connection-singleton'), |
14 | | - logmet = require('logmet-client'); |
| 12 | +const LogmetProducer = require('logmet-client').LogmetProducer; |
15 | 13 |
|
16 | | -module.exports = { |
17 | | - appender: appender, |
18 | | - configure: configure, |
19 | | - shutdown: shutdown |
20 | | -}; |
| 14 | +function logmetAppender(logmetClientProducer, spaceId, layout, timezoneOffset) { |
21 | 15 |
|
22 | | -function sendData(options, tlsOpts, log) { |
23 | | - var event = buildEvent(log, options); |
24 | | - logmetConnection.producer.sendData(event, log.categoryName, options.space_id, function(/*error, status*/) { |
25 | | - // message is dropped if an error is returned, errors already logged by logmet client |
26 | | - }); |
27 | | -} |
28 | | - |
29 | | -function buildEvent(log, options) { |
30 | | - // build up message to send |
31 | | - let event = {}; |
32 | | - let fields = options.fields; |
| 16 | + const appender = (loggingEvent) => { |
| 17 | + logmetClientProducer.sendData(layout(loggingEvent, timezoneOffset), spaceId); |
| 18 | + }; |
33 | 19 |
|
34 | | - if (fields.level_field_name) { |
35 | | - event[fields.level_field_name] = log.level && log.level.levelStr; |
36 | | - } |
37 | | - if (fields.timestamp_field_name) { |
38 | | - event[fields.timestamp_field_name] = log.startTime && log.startTime.toISOString(); |
39 | | - } |
40 | | - if (fields.data_field_augment && log.data && log.data.length === 1 && typeof log.data[0] === 'object') { |
41 | | - let customDynamicFields = log.data[0]; |
42 | | - for (let customDynamicFieldName in customDynamicFields) { |
43 | | - event[customDynamicFieldName] = customDynamicFields[customDynamicFieldName]; |
| 20 | + appender.shutdown = (callback) => { |
| 21 | + if (logmetClientProducer) { |
| 22 | + logmetClientProducer.terminate(callback); |
44 | 23 | } |
45 | | - } else if (fields.data_field_name) { |
46 | | - event[fields.data_field_name] = log.data && log.data.join(' | '); |
47 | | - } |
48 | | - for (let staticFieldName in fields.static_fields) { |
49 | | - event[staticFieldName] = fields.static_fields[staticFieldName]; |
50 | | - } |
51 | | - for (let processFieldName in fields.process_fields) { |
52 | | - event[processFieldName] = process[fields.process_fields[processFieldName]]; |
53 | | - } |
54 | | - for (let envFieldName in fields.env_fields) { |
55 | | - event[envFieldName] = process.env[fields.env_fields[envFieldName]]; |
56 | | - } |
57 | | - |
58 | | - return event; |
59 | | -} |
60 | | - |
61 | | -function appender(options, tlsOpts) { |
62 | | - logmetConnection.producer = new logmet.LogmetProducer(tlsOpts.host, tlsOpts.port, options.space_id, options.logging_token, false, {bufferSize: logmetConnection.BUFFER_SIZE}); |
63 | | - logmetConnection.producer.connect(function(error, status) { |
64 | | - if (error) { |
65 | | - util.log('Logmet Appender: Connection with Logmet failed. ERROR: ' + error); |
66 | | - } else if (status.handshakeCompleted) { |
67 | | - util.log('Logmet Appender: LogmetClient is ready to send data.'); |
| 24 | + else { |
| 25 | + callback(); |
68 | 26 | } |
69 | | - }); |
70 | | - return sendData.bind(this, options, tlsOpts); |
| 27 | + }; |
| 28 | + return appender; |
71 | 29 | } |
72 | 30 |
|
73 | | -function configure(config) { |
74 | | - if (process.env.log4js_logmet_enabled !== 'true') return function() {}; |
| 31 | +function configure(config, layouts) { |
| 32 | + if (process.env.log4js_logmet_enabled !== 'true') { return () => {}; } |
75 | 33 |
|
76 | | - const defaultFields = { |
77 | | - 'level_field_name': 'loglevel', |
78 | | - 'timestamp_field_name': 'logtime', |
79 | | - 'data_field_name': 'message', |
| 34 | + const options = {}; |
80 | 35 |
|
81 | | - 'static_fields': { |
82 | | - 'component': process.env.log4js_logmet_component || config.options && config.options.component |
83 | | - }, |
84 | | - 'env_fields': { |
85 | | - 'host-ip': 'CF_INSTANCE_IP', |
86 | | - 'instance-id': 'CF_INSTANCE_INDEX' |
87 | | - } |
88 | | - }; |
| 36 | + options.host = process.env.log4js_logmet_logging_host || config.logging_host; |
| 37 | + options.port = process.env.log4js_logmet_logging_port || config.logging_port; |
| 38 | + options.spaceId = process.env.log4js_logmet_space_id || config.space_id; |
| 39 | + options.loggingToken = process.env.log4js_logmet_logging_token || config.logging_token; |
89 | 40 |
|
90 | | - const options = { |
91 | | - logging_token: process.env.log4js_logmet_logging_token || config.options && config.options.logging_token, |
92 | | - space_id: process.env.log4js_logmet_space_id || config.options && config.options.space_id, |
93 | | - fields: (config.options && config.options.fields) || defaultFields |
94 | | - }; |
| 41 | + for (let option in options) { |
| 42 | + if (!options[option]) { |
| 43 | + console.log(`Logmet appender: ${ option } not specified`); |
| 44 | + return () => {}; |
| 45 | + } |
| 46 | + } |
95 | 47 |
|
96 | | - const tlsOpts = { |
97 | | - host: process.env.log4js_logmet_logging_host || config.options && config.options.logging_host, |
98 | | - port: process.env.log4js_logmet_logging_port || config.options && config.options.logging_port, |
99 | | - secureProtocol: logmetConnection.DEFAULT_SECURE_PROTOCOL, |
100 | | - rejectUnauthorized: logmetConnection.DEFAULT_REJECT_UNAUTHORIZED |
| 48 | + let layout = (logEvent) => { |
| 49 | + return { |
| 50 | + 'component': process.env.log4js_logmet_component || config.component, |
| 51 | + 'host-ip': process.env.CF_INSTANCE_IP, |
| 52 | + 'instance-id': process.env.CF_INSTANCE_INDEX, |
| 53 | + 'loglevel': logEvent.level.levelStr, |
| 54 | + 'msg_timestamp': logEvent.startTime.toISOString(), |
| 55 | + 'message': logEvent.data.join(' | '), |
| 56 | + 'type': logEvent.categoryName |
| 57 | + }; |
101 | 58 | }; |
102 | | - |
103 | | - var optionsInvalid = false; |
104 | | - |
105 | | - for (var i in options) { |
106 | | - if (!options[i]) { |
107 | | - util.log('Logmet Appender: ' + i + ' not specified'); |
108 | | - optionsInvalid = true; |
109 | | - } |
| 59 | + if (config.layout) { |
| 60 | + layout = layouts.layout(config.layout.type, config.layout); |
110 | 61 | } |
111 | 62 |
|
112 | | - if (optionsInvalid) return function() {}; |
| 63 | + console.log('Logmet appender configured'); |
113 | 64 |
|
114 | | - if (config.appender) { |
115 | | - log4js.loadAppender(config.appender.type); |
116 | | - config.actualAppender = log4js.appenderMakers[config.appender.type](config.appender); |
117 | | - } |
| 65 | + const logmetClientProducer = new LogmetProducer(options.host, options.port, options.spaceId, options.loggingToken, false, |
| 66 | + {bufferSize: process.env.log4js_logmet_buffer_size || 10000}); |
118 | 67 |
|
119 | | - util.log('Logmet Appender configured'); |
120 | | - return appender(options, tlsOpts); |
| 68 | + logmetClientProducer.connect((error, status) => { |
| 69 | + if (error) { |
| 70 | + console.error(`Logmet appender: Connection with Logmet failed. Details: ${ error }`); |
| 71 | + } else if (status.handshakeCompleted) { |
| 72 | + console.log('Logmet appender: LogmetClient is ready to send data.'); |
| 73 | + } |
| 74 | + }); |
| 75 | + return logmetAppender(logmetClientProducer, options.spaceId, layout, config.timezoneOffset); |
121 | 76 | } |
122 | 77 |
|
123 | | -function shutdown(callback) { |
124 | | - if (logmetConnection.producer) { |
125 | | - logmetConnection.producer.terminate(callback); |
126 | | - } |
127 | | - else { |
128 | | - callback(); |
129 | | - } |
130 | | -} |
| 78 | +module.exports.configure = configure; |
131 | 79 |
|
0 commit comments