export type LogLevel = 'info' | 'trace' | 'debug' | 'warn' | 'error' | 'query' ; export interface RawRustLog { timestamp : string ; level : LogLevel ; target : string ; fields : LogFields ; } export interface RustLog { timestamp : Date ; level : LogLevel ; target : string ; fields : LogFields ; } export interface RustError { is_panic : boolean ; message : string ; backtrace ? : string ; } export function getMessage ( log ) { if ( typeof log === 'string' ) { return log ; } else if ( isRustError ( log ) ) { return getBacktraceFromRustError ( log ) ; } else if ( isRustLog ( log ) ) { return getBacktraceFromLog ( log ) ; } return JSON . stringify ( log ) ; } export function getBacktraceFromLog ( log ) { if ( log . fields ?. message ) { let str = log . fields ?. message ; if ( log . fields ?. file ) { str += ` in ${ log . fields . file }` ; if ( log . fields ?. line ) { str += `:${ log . fields . line }` ; } if ( log . fields ?. column ) { str += `:${ log . fields . column }` ; } } if ( log . fields ?. reason ) { str += `\n${ log . fields ?. reason }` ; } return str ; } return 'Unknown error' ; } export function getBacktraceFromRustError ( err ) { let str = '' ; if ( err . is_panic ) { str += `PANIC` ; } if ( err . backtrace ) { str += ` in ${ err . backtrace }` ; } if ( err . message ) { str += `\n${ err . message }` ; } return str ; } export function isRustLog ( e ) { return e . timestamp && typeof e . level === 'string' && typeof e . target === 'string' ; } export function isRustErrorLog ( e ) { return isRustLog ( e ) && ( e . level === 'error' || e . fields ?. message ?. includes ( 'fatal error' ) ) ; } export function isRustError ( e ) { return typeof e . is_panic !== 'undefined' ; } export type LogFields = { [ key ] : any ; } ; export interface PanicLogFields { message : 'PANIC' ; reason : string ; file : string ; line : string ; column : number ; } export interface InfoLogFields { message : string ; 'log.target' : string ; 'log.module_path' : string ; 'log.file' : string ; 'log.line' : number ; } export interface QueryLogFields { query : string ; item_type : string ; params : string ; duration_ms : number ; } export interface Log { message : string ; level : LogLevel ; date : Date ; application : string ; [ key ] : string | Date ; } export function convertLog ( rustLog ) { const isQuery = isQueryLog ( rustLog . fields ) ; const level = isQuery ? 'query' : ( rustLog . level . toLowerCase ( ) as LogLevel ) ; return { ... rustLog , level , timestamp : new Date ( new Date ( ) . getFullYear ( ) + ' ' + rustLog . timestamp ) , } ; } function isQueryLog ( fields ) { return Boolean ( fields . query ) ; }