/**
 * Copyright 2021 Opstrace, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ import { strict as assert } from "assert" ; import { format , createLogger , transports , config , Logger } from "winston" ; const logFormat = format . printf ( ( { level , message , timestamp , stack } ) => `${ timestamp } ${ level }: ${ message }${ stack ? ": " + stack : "" }` ) ; export let log ; let winstonStderrTransport ; export function setLogger ( logger ) { if ( log !== undefined ) { log . debug ( "logger already defined. current logger: %s, new logger: %s" , log , logger ) ; } log = logger ; } export interface CliLogOptions { filePath ? : string ; fileLevel ? : string ; stderrLevel : string ; } export function buildLogger ( opts ) { const stderrtransp = new transports . Console ( { stderrLevels : Object . keys ( config . syslog . levels ) , level : opts . stderrLevel , format : format . combine ( format . splat ( ) , format . timestamp ( ) , format . colorize ( ) , logFormat ) } ) ; const ts = [ stderrtransp ] ; if ( [ opts . filePath , opts . fileLevel ] . filter ( v => v !== undefined ) . length == 1 ) { throw Error ( "logfileLevel requires logfilePath and vice versa" ) ; } if ( opts . fileLevel !== undefined ) { ts . push ( new transports . File ( { filename : opts . filePath , level : opts . fileLevel , format : format . combine ( format . splat ( ) , format . timestamp ( ) , logFormat ) } ) ) ; } const logger = createLogger ( { levels : config . syslog . levels , transports : ts } ) ; winstonStderrTransport = stderrtransp ; return logger ; } export function changeStderrLogLevel ( stderrLevel ) { assert ( stderrLevel in config . syslog . levels ) ; winstonStderrTransport . level = stderrLevel ; } export function debugLogErrorDetail ( err ) { if ( err === undefined ) { log . debug ( "debugLogErrorDetail: `err` obj is undefined. Sadness." ) ; return ; } let s ; s = `err.name: ${ err . name }` ; s += `err.code: ${ err . code }` ; s += `err.message: ${ err . message }` ; s += `err.stack: ${ err . stack }` ; log . debug ( "err detail: %s" , s ) ; try { log . debug ( "JSON representation of err: %s" , JSON . stringify ( err , null , 2 ) ) ; } catch ( e ) { log . debug ( "could not json-serialize error: %s" , e ) ; } } setLogger ( buildLogger ( { stderrLevel : "debug" } ) ) ;