1 | var bunyan = require('bunyan');
|
2 | var bformat = require('bunyan-format');
|
3 | var formatStdOut = bformat({levelInString: true}, process.stdout);
|
4 | var SlJsInfra = require('sl-js-infra').SlJsInfra;
|
5 | var blackholeLogger = require('bunyan-blackhole');
|
6 |
|
7 | var TRACE = 10;
|
8 | var DEBUG = 20;
|
9 | var INFO = 30;
|
10 | var WARN = 40;
|
11 | var ERROR = 50;
|
12 | var FATAL = 60;
|
13 |
|
14 | function mapLevelToName(level) {
|
15 | switch (level) {
|
16 | case TRACE:
|
17 | return 'TRACE';
|
18 | case DEBUG:
|
19 | return 'DEBUG';
|
20 | case INFO:
|
21 | return 'INFO';
|
22 | case WARN:
|
23 | return 'WARN';
|
24 | case ERROR:
|
25 | return 'ERROR';
|
26 | case FATAL:
|
27 | return 'FATAL';
|
28 | }
|
29 | }
|
30 |
|
31 | function BunyanLogger(config){
|
32 | this.buffer = [];
|
33 | this.bufferLength = config.bufferLength || 50;
|
34 | this.bufferTimeout = config.bufferTimeout || 3000;
|
35 | this.maxConnections = 10;
|
36 | this.currentConnections = 0;
|
37 | this.config = config;
|
38 | }
|
39 |
|
40 | BunyanLogger.prototype.write = function(data){
|
41 | data.level = mapLevelToName(data.level);
|
42 | this.buffer.push(data);
|
43 | this.checkBuffer(false, function (err) {});
|
44 | };
|
45 |
|
46 | BunyanLogger.prototype.processBuffer = function(callback){
|
47 | clearTimeout(this._timeoutId);
|
48 |
|
49 | var entries = this.buffer.slice();
|
50 | this.buffer = [];
|
51 | if (this.currentConnections == this.maxConnections) {
|
52 | return callback(null);
|
53 | }
|
54 |
|
55 | this._sendLogs(entries, function (err) {
|
56 | if (err){
|
57 | console.error("[LOG SUBMISSION] Failed to send logs to Sealights. Error: " + err);
|
58 | callback(err);
|
59 | }
|
60 | else {
|
61 | callback(null);
|
62 | }
|
63 | });
|
64 | };
|
65 |
|
66 | BunyanLogger.prototype.checkBuffer = function(isLastProcess, callback){
|
67 | var bunyanLogger = this;
|
68 |
|
69 | if (isLastProcess) {
|
70 | this.bufferLength = 1;
|
71 | this.bufferTimeout = 0;
|
72 | }
|
73 |
|
74 | if (!this.buffer.length) {
|
75 | return callback(null);
|
76 | }
|
77 |
|
78 | if(this.buffer.length >= this.bufferLength){
|
79 | return this.processBuffer(callback);
|
80 | }
|
81 |
|
82 | if(this.bufferTimeout){
|
83 | clearTimeout(this._timeoutId);
|
84 |
|
85 | this._timeoutId = setTimeout(
|
86 | function(){
|
87 | bunyanLogger.processBuffer(callback);
|
88 | },
|
89 | this.bufferTimeout
|
90 | );
|
91 | }
|
92 | };
|
93 |
|
94 | BunyanLogger.prototype._sendLogs = function sendLogs(entries, callback) {
|
95 | var data = {
|
96 | customerId: this.config.customerId,
|
97 | appName: this.config.appName,
|
98 | creationTime: new Date().valueOf(),
|
99 | environment: {
|
100 | environmentName: this.config.environment || "null"
|
101 | },
|
102 | log: entries.map(function (entry) {
|
103 | return JSON.stringify(entry)
|
104 | }).join("\n")
|
105 | };
|
106 | if (!data.customerId || !data.appName) {
|
107 | return callback(new Error("[LOG SUBMISSION] customerId and appName are required to send logs"))
|
108 | }
|
109 |
|
110 | this.currentConnections += 1;
|
111 |
|
112 | var that = this;
|
113 | var backendProxy = new SlJsInfra.BackendProxy(this.config, nullLogger());
|
114 | backendProxy.submitLogs(data, function(err, body){
|
115 | that.currentConnections -= 1;
|
116 | callback(err);
|
117 | });
|
118 | };
|
119 |
|
120 | var nullLogger = function () {
|
121 | return blackholeLogger();
|
122 | };
|
123 |
|
124 | function getLogLevel(){
|
125 | return process.env.SL_LOG_LEVEL || "info";;
|
126 | }
|
127 |
|
128 | var consoleFileLogger = function (name) {
|
129 | var loggerConfig = {
|
130 | name: name || "CIA",
|
131 | streams: []
|
132 | };
|
133 | var logLevel = getLogLevel();
|
134 | if (process.env.NODE_DEBUG == "sl" || process.env.NODE_DEBUG == "sl-console") {
|
135 | loggerConfig.streams.push({level: logLevel, stream: formatStdOut})
|
136 | }
|
137 | if (process.env.NODE_DEBUG == "sl-file") {
|
138 | loggerConfig.streams.push({level: logLevel, path: "sl.node.log"})
|
139 | }
|
140 | return bunyan.createLogger(loggerConfig);
|
141 | };
|
142 |
|
143 | var logger = function (config) {
|
144 | var remoteStream;
|
145 | var environment = {environmentName: "null"};
|
146 | if (config.environmentName) {
|
147 | environment = {environmentName: config.environmentName}
|
148 | }
|
149 | if (config.environment && config.environment.environmentName) {
|
150 | environment = config.environment;
|
151 | }
|
152 | var loggerConfig = {
|
153 | name: "CIA",
|
154 | streams: []
|
155 | };
|
156 |
|
157 | var logLevel = getLogLevel();
|
158 | if (process.env.NODE_DEBUG == "sl" || process.env.NODE_DEBUG == "sl-console" || config.NODE_DEBUG == "sl") {
|
159 | loggerConfig.streams.push({level: logLevel, stream: formatStdOut})
|
160 | }
|
161 | if (process.env.NODE_DEBUG == "sl-file" || config.NODE_DEBUG == "sl-file") {
|
162 | loggerConfig.streams.push({level: logLevel, path: "sl.node.log"})
|
163 | }
|
164 | if (config.sendLogs) {
|
165 | remoteStream = new BunyanLogger(config);
|
166 | loggerConfig.streams.push({level: logLevel, type: "raw", stream: remoteStream});
|
167 | }
|
168 | var bunyanLogger = bunyan.createLogger(loggerConfig);
|
169 | bunyanLogger.remoteStream = remoteStream;
|
170 | return bunyanLogger
|
171 | };
|
172 |
|
173 | module.exports.BunyanLogger = BunyanLogger;
|
174 | module.exports.logger = logger;
|
175 | module.exports.nullLogger = nullLogger;
|
176 | module.exports.consoleFileLogger = consoleFileLogger; |
\ | No newline at end of file |