1/*
2 * log.ts
3 *
4 * Copyright (C) 2021 by RStudio, PBC
5 *
6 * Unless you have received this program directly from RStudio pursuant
7 * to the terms of a commercial license agreement with RStudio, then
8 * this program is licensed to you under the terms of version 3 of the
9 * GNU Affero General Public License. This program is distributed WITHOUT
10 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
12 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
13 *
14 */
15
16import { coreState } from './core-state';
17
18/**
19 * Enum representing logging detail level
20 */
21export enum LogLevel {
22  OFF = 0,       // No messages will be logged
23  ERR = 1,       // Error messages will be logged
24  WARN = 2,      // Warning and error messages will be logged
25  INFO = 3,      // Info, warning, and error messages will be logged
26  DEBUG = 4      // All messages will be logged
27}
28
29export interface Logger {
30  logError(err: Error): void;
31  logErrorMessage(message: string): void;
32  logWarning(warning: string): void;
33  logInfo(message: string): void;
34  logDebug(message: string): void;
35  logDiagnostic(message: string): void;
36  logDiagnosticEnvVar(name: string): void;
37}
38
39export interface LogOptions {
40  logger?: Logger;
41  logLevel: LogLevel;
42  showDiagnostics: boolean;
43}
44
45/* eslint-disable @typescript-eslint/no-unused-vars */
46/* eslint-disable @typescript-eslint/no-empty-function */
47export class NullLogger implements Logger {
48  logError(err: Error): void {
49  }
50  logErrorMessage(message: string): void {
51  }
52  logInfo(message: string): void {
53  }
54  logWarning(warning: string): void {
55  }
56  logDebug(message: string): void {
57  }
58  logDiagnostic(message: string): void {
59  }
60  logDiagnosticEnvVar(name: string): void {
61  }
62}
63
64export function logger(): Logger {
65  const logger = coreState().logOptions.logger;
66  if (!logger) {
67    throw Error('Logger not set');
68  }
69  return logger;
70}
71
72/**
73 * @returns Current logging level
74 */
75export function logLevel(): LogLevel {
76  return coreState().logOptions.logLevel;
77}
78
79export function setLogger(logger: Logger): void {
80  coreState().logOptions.logger = logger;
81}
82
83export function enableDiagnosticsOutput(): void {
84  coreState().logOptions.showDiagnostics = true;
85}
86
87export function showDiagnosticsOutput(): boolean {
88  return coreState().logOptions.showDiagnostics;
89}
90
91/**
92 * @param level minimum logging level
93 */
94export function setLoggerLevel(level: LogLevel): void {
95  coreState().logOptions.logLevel = level;
96}
97
98/**
99 * Convert a string log level (e.g. 'WARN') to LogLevel enum.
100 *
101 * @param level String representation of log level
102 * @param defaultLevel Default logging level if unable to parse input
103 * @returns LogLevel enum value
104 */
105export function parseCommandLineLogLevel(level: string, defaultLevel: LogLevel): LogLevel {
106  level = level.toUpperCase();
107  switch (level) {
108  case 'OFF':
109    return LogLevel.OFF;
110  case 'ERR':
111    return LogLevel.ERR;
112  case 'WARN':
113    return LogLevel.WARN;
114  case 'INFO':
115    return LogLevel.INFO;
116  case 'DEBUG':
117    return LogLevel.DEBUG;
118  default:
119    return defaultLevel;
120  }
121}