UNPKG

6.35 kBJavaScriptView Raw
1"use strict";
2// *****************************************************************************
3// Copyright (C) 2018 Ericsson and others.
4//
5// This program and the accompanying materials are made available under the
6// terms of the Eclipse Public License v. 2.0 which is available at
7// http://www.eclipse.org/legal/epl-2.0.
8//
9// This Source Code may also be made available under the following Secondary
10// Licenses when the conditions for such availability set forth in the Eclipse
11// Public License v. 2.0 are satisfied: GNU General Public License, version 2
12// with the GNU Classpath Exception which is available at
13// https://www.gnu.org/software/classpath/license.html.
14//
15// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
16// *****************************************************************************
17var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
18 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
19 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
20 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
21 return c > 3 && r && Object.defineProperty(target, key, r), r;
22};
23Object.defineProperty(exports, "__esModule", { value: true });
24exports.LogLevelCliContribution = void 0;
25const inversify_1 = require("inversify");
26const logger_1 = require("../common/logger");
27const fs = require("fs-extra");
28const nsfw = require("nsfw");
29const event_1 = require("../common/event");
30const path = require("path");
31/**
32 * Parses command line switches related to log levels, then watches the log
33 * levels file (if specified) for changes. This is the source of truth for
34 * what the log level per logger should be.
35 */
36let LogLevelCliContribution = class LogLevelCliContribution {
37 constructor() {
38 this._logLevels = {};
39 /**
40 * Log level to use for loggers not specified in `logLevels`.
41 */
42 this._defaultLogLevel = logger_1.LogLevel.INFO;
43 this.logConfigChangedEvent = new event_1.Emitter();
44 }
45 get defaultLogLevel() {
46 return this._defaultLogLevel;
47 }
48 get logLevels() {
49 return this._logLevels;
50 }
51 configure(conf) {
52 conf.option('log-level', {
53 description: 'Sets the default log level',
54 choices: Array.from(logger_1.LogLevel.strings.values()),
55 nargs: 1,
56 });
57 conf.option('log-config', {
58 description: 'Path to the JSON file specifying the configuration of various loggers',
59 type: 'string',
60 nargs: 1,
61 });
62 }
63 async setArguments(args) {
64 if (args['log-level'] !== undefined && args['log-config'] !== undefined) {
65 throw new Error('--log-level and --log-config are mutually exclusive.');
66 }
67 if (args['log-level'] !== undefined) {
68 this._defaultLogLevel = this.readLogLevelString(args['log-level'], 'Unknown log level passed to --log-level');
69 }
70 if (args['log-config'] !== undefined) {
71 let filename = args['log-config'];
72 try {
73 filename = path.resolve(filename);
74 await this.slurpLogConfigFile(filename);
75 await this.watchLogConfigFile(filename);
76 }
77 catch (e) {
78 console.error(`Error reading log config file ${filename}: ${e}`);
79 }
80 }
81 }
82 watchLogConfigFile(filename) {
83 return nsfw(filename, async (events) => {
84 try {
85 for (const event of events) {
86 switch (event.action) {
87 case 0 /* CREATED */:
88 case 2 /* MODIFIED */:
89 await this.slurpLogConfigFile(filename);
90 this.logConfigChangedEvent.fire(undefined);
91 break;
92 }
93 }
94 }
95 catch (e) {
96 console.error(`Error reading log config file ${filename}: ${e}`);
97 }
98 }).then((watcher) => {
99 watcher.start();
100 });
101 }
102 async slurpLogConfigFile(filename) {
103 try {
104 const content = await fs.readFile(filename, 'utf-8');
105 const data = JSON.parse(content);
106 let newDefaultLogLevel = logger_1.LogLevel.INFO;
107 if ('defaultLevel' in data) {
108 newDefaultLogLevel = this.readLogLevelString(data['defaultLevel'], `Unknown default log level in ${filename}`);
109 }
110 const newLogLevels = {};
111 if ('levels' in data) {
112 const loggers = data['levels'];
113 for (const logger of Object.keys(loggers)) {
114 const levelStr = loggers[logger];
115 newLogLevels[logger] = this.readLogLevelString(levelStr, `Unknown log level for logger ${logger} in ${filename}`);
116 }
117 }
118 this._defaultLogLevel = newDefaultLogLevel;
119 this._logLevels = newLogLevels;
120 console.log(`Successfully read new log config from ${filename}.`);
121 }
122 catch (e) {
123 throw new Error(`Error reading log config file ${filename}: ${e.message}`);
124 }
125 }
126 get onLogConfigChanged() {
127 return this.logConfigChangedEvent.event;
128 }
129 logLevelFor(loggerName) {
130 const level = this._logLevels[loggerName];
131 if (level !== undefined) {
132 return level;
133 }
134 else {
135 return this.defaultLogLevel;
136 }
137 }
138 /**
139 * Converts the string to a `LogLevel`. Throws an error if invalid.
140 */
141 readLogLevelString(levelStr, errMessagePrefix) {
142 const level = logger_1.LogLevel.fromString(levelStr);
143 if (level === undefined) {
144 throw new Error(`${errMessagePrefix}: "${levelStr}".`);
145 }
146 return level;
147 }
148};
149LogLevelCliContribution = __decorate([
150 (0, inversify_1.injectable)()
151], LogLevelCliContribution);
152exports.LogLevelCliContribution = LogLevelCliContribution;
153//# sourceMappingURL=logger-cli-contribution.js.map
\No newline at end of file