import { app } from "electron" ; import { ProjectApiAnalysisResult , } from "@porting-assistant/react/src/models/project" ; import { SolutionDetails } from "@porting-assistant/react/src/models/solution" ; import fs from "fs" ; import log , { LogMessage , LevelOption } from "electron-log" ; import { Connection } from "electron-cgi/connection" ; import { putMetricData } from "./electron-metrics" ; import { localStore } from "../preload-localStore" ; import path from "path" ; import winston from "winston" ; import DailyRotateFile from "winston-daily-rotate-file" ; const electronLogName = "portingAssistant-electron-%DATE%" ; const reactLogName = "portingAssistant-react-%DATE%" ; const dirName = path . join ( app . getPath ( "userData" ) , "logs" ) ; if ( ! fs . existsSync ( dirName ) ) fs . mkdir ( dirName , ( err ) => { console . log ( "Telemetry Directory Creation Failed." ) ; } ) ; var winstonTransportsElectron = [ new DailyRotateFile ( { datePattern : "YYYY-MM-DD" , extension : ".log" , filename : electronLogName , dirname : dirName , maxFiles : 20 , format : winston . format . combine ( winston . format . printf ( ( info ) => { return `${ info . message }` ; } ) ) , } ) , ] ; var winstonTransportsReact = [ new DailyRotateFile ( { datePattern : "YYYY-MM-DD" , extension : ".log" , filename : reactLogName , dirname : dirName , maxFiles : 20 , format : winston . format . combine ( winston . format . printf ( ( info ) => { return `${ info . message }` ; } ) ) , } ) , ] ; var electronLogger = winston . createLogger ( { transports : winstonTransportsElectron , exitOnError : false , } ) ; var reactLogger = winston . createLogger ( { transports : winstonTransportsReact , exitOnError : false , } ) ; export const logReactMetrics = ( response ) => { const targetFramework = localStore . get ( "targetFramework" ) . id || "net6.0" ; const errorMetric = { Metrics : { Status : "failed" , } , TimeStamp : new Date ( ) , ListMetrics : [ { Error : response , } , ] , Dimensions : [ { Name : "metricsType" , Value : "portingAssistant-react-errors" , } , { Name : "portingAssistantVersion" , Value : app . getVersion ( ) , } , { Name : "targetFramework" , Value : targetFramework , } , ] , } ; reactLogger . info ( JSON . stringify ( errorMetric ) ) ; } ; export const logReactError = ( source , message , response ) => { const cur = new Date ( ) ; let curTimeArr = cur . toISOString ( ) . split ( 'T' ) ; let curDate = curTimeArr [ 0 ] ; let curTime = curTimeArr [ 1 ] . split ( '.' ) [ 0 ] ; let appVersion = app . getVersion ( ) ; let errorMessage = `[${ curDate } ${ curTime } ERR] (${ appVersion }) ${ source }: ${ message }\n${ response }` ; reactLogger . info ( errorMessage ) ; } ; export const logSolutionMetrics = ( response , time ) => { try { if ( response . status . status === "Failure" ) { errorHandler ( response , "Solutions" ) ; } else if ( response . status . status === "Success" ) { const solutionDetails = response . value ; const targetFramework = localStore . get ( "targetFramework" ) . id || "net6.0" ; let allpackages = new Set ( solutionDetails . projects . flatMap ( ( project ) => { return project . packageReferences ; } ) . filter ( ( p ) => p !== undefined || p !== null ) ) ; } } catch ( err ) { } } ; export const logApiMetrics = ( response ) => { try { if ( response . status . status !== "Success" ) { return ; } const projectAnalysis = response . value ; const targetFramework = localStore . get ( "targetFramework" ) . id || "net6.0" ; if ( projectAnalysis . sourceFileAnalysisResults != null && projectAnalysis . projectFile != null ) { const apis = projectAnalysis . sourceFileAnalysisResults . flatMap ( ( sourceFileAnalysisResults ) => sourceFileAnalysisResults . apiAnalysisResults . map ( ( invocation ) => { return { name : invocation . codeEntityDetails . name , namespace : invocation . codeEntityDetails . namespace , originalDefinition : invocation . codeEntityDetails ?. signature , compatibility : invocation . compatibilityResults [ targetFramework ] ?. compatibility , } ; } ) ) ; } } catch ( err ) { } } ; export const registerLogListeners = ( connection ) => { const targetFramework = localStore . get ( "targetFramework" ) . id || "net6.0" ; const transport = ( message ) => { try { const str = message . data [ 0 ] ; if ( str ) { const logs = { portingAssistantVersion : app . getVersion ( ) , targetFramework : targetFramework , content : str , } ; electronLogger . info ( JSON . stringify ( logs ) ) ; } } catch ( err ) { } } ; transport . level = "warn" as LevelOption ; log . transports [ "electron" ] = transport ; connection . on ( "onApiAnalysisUpdate" , ( response ) => { try { logApiMetrics ( response ) ; } catch ( err ) { } } ) ; } ; export const startTimer = ( ) => { const time = new Date ( ) . getTime ( ) ; return ( ) => { const endTime = new Date ( ) ; const elapseTime = endTime . getTime ( ) - time ; return elapseTime ; } ; } ; export const errorHandler = ( response , metricsType ) => { const errorValue = response . errorValue ; const error = response . status . error ; const targetFramework = localStore . get ( "targetFramework" ) . id || "net6.0" ; putMetricData ( "portingAssistant-backend-errors" , "Error" , "Count" , 1 , [ { Name : "metricsType" , Value : metricsType , } , { Name : "portingAssistantVersion" , Value : app . getVersion ( ) , } , { Name : "targetFramework" , Value : targetFramework , } , ] ) . catch ( ( error ) => { return ; } ) ; } ;