{
  "version": 3,
  "sources": ["../../../../src/processors/file-processor.ts"],
  "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { appendFileSync, mkdirSync, openSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { type LogFilter, LogLevel } from '../config';\nimport { type LogProcessor, shouldLog } from '../context';\n\n// Amount of time to retry writing after encountering EAGAIN before giving up.\nconst EAGAIN_MAX_DURATION = 1000;\n\n/**\n * Create a file processor.\n * @param path - Path to log file to create or append to, or existing open file descriptor e.g. stdout.\n * @param levels - Log levels to process. Takes preference over Filters.\n * @param filters - Filters to apply.\n */\nexport const createFileProcessor = ({\n  pathOrFd,\n  levels,\n  filters,\n}: {\n  pathOrFd: string | number;\n  levels: LogLevel[];\n  filters?: LogFilter[];\n}): LogProcessor => {\n  let fd: number | undefined;\n\n  return (config, entry) => {\n    if (levels.length > 0 && !levels.includes(entry.level)) {\n      return;\n    }\n    if (!shouldLog(entry, filters)) {\n      return;\n    }\n\n    if (typeof pathOrFd === 'number') {\n      fd = pathOrFd;\n    } else {\n      try {\n        mkdirSync(dirname(pathOrFd));\n      } catch {}\n      fd = openSync(pathOrFd, 'a');\n    }\n\n    const record = {\n      level: entry.level,\n      message: entry.message,\n      timestamp: entry.timestamp,\n      meta: entry.computedMeta,\n      context: entry.computedContext,\n      error: entry.computedError,\n    };\n    let retryTS: number = 0;\n\n    // Retry writing if EAGAIN is encountered.\n    //\n    // Node may set stdout and stderr to non-blocking. https://github.com/nodejs/node/issues/42826\n    // This can cause EAGAIN errors when writing to them.\n    // In order to not drop logs, make log methods asynchronous, or deal with buffering/delayed writes, spin until write succeeds.\n\n    while (true) {\n      try {\n        return appendFileSync(fd, JSON.stringify(record) + '\\n');\n      } catch (err: any) {\n        if (err.code !== 'EAGAIN') {\n          throw err;\n        }\n        if (retryTS === 0) {\n          retryTS = performance.now();\n        } else {\n          if (performance.now() - retryTS > EAGAIN_MAX_DURATION) {\n            console.log(`could not write after ${EAGAIN_MAX_DURATION}ms of EAGAIN failures, giving up`);\n            throw err;\n          }\n        }\n      }\n    }\n  };\n};\n\nlet logFilePath: string | undefined;\nconst getLogFilePath = () => {\n  logFilePath ??=\n    process.env.LOG_FILE ??\n    (process.env.HOME ? `${process.env.HOME}/.dxlog/${new Date().toISOString()}.log` : undefined);\n\n  return logFilePath!;\n};\n\nexport const FILE_PROCESSOR: LogProcessor = createFileProcessor({\n  pathOrFd: getLogFilePath(),\n  levels: [LogLevel.ERROR, LogLevel.WARN, LogLevel.INFO, LogLevel.TRACE],\n});\n"],
  "mappings": ";;;;;;;AAIA,SAASA,gBAAgBC,WAAWC,gBAAgB;AACpD,SAASC,eAAe;AAMxB,IAAMC,sBAAsB;AAQrB,IAAMC,sBAAsB,CAAC,EAClCC,UACAC,QACAC,QAAO,MAKR;AACC,MAAIC;AAEJ,SAAO,CAACC,QAAQC,UAAAA;AACd,QAAIJ,OAAOK,SAAS,KAAK,CAACL,OAAOM,SAASF,MAAMG,KAAK,GAAG;AACtD;IACF;AACA,QAAI,CAACC,UAAUJ,OAAOH,OAAAA,GAAU;AAC9B;IACF;AAEA,QAAI,OAAOF,aAAa,UAAU;AAChCG,WAAKH;IACP,OAAO;AACL,UAAI;AACFU,kBAAUC,QAAQX,QAAAA,CAAAA;MACpB,QAAQ;MAAC;AACTG,WAAKS,SAASZ,UAAU,GAAA;IAC1B;AAEA,UAAMa,SAAS;MACbL,OAAOH,MAAMG;MACbM,SAAST,MAAMS;MACfC,WAAWV,MAAMU;MACjBC,MAAMX,MAAMY;MACZC,SAASb,MAAMc;MACfC,OAAOf,MAAMgB;IACf;AACA,QAAIC,UAAkB;AAQtB,WAAO,MAAM;AACX,UAAI;AACF,eAAOC,eAAepB,IAAIqB,KAAKC,UAAUZ,MAAAA,IAAU,IAAA;MACrD,SAASa,KAAU;AACjB,YAAIA,IAAIC,SAAS,UAAU;AACzB,gBAAMD;QACR;AACA,YAAIJ,YAAY,GAAG;AACjBA,oBAAUM,YAAYC,IAAG;QAC3B,OAAO;AACL,cAAID,YAAYC,IAAG,IAAKP,UAAUxB,qBAAqB;AACrDgC,oBAAQC,IAAI,yBAAyBjC,mBAAAA,kCAAqD;AAC1F,kBAAM4B;UACR;QACF;MACF;IACF;EACF;AACF;AAEA,IAAIM;AACJ,IAAMC,iBAAiB,MAAA;AACrBD,kBACEE,QAAQC,IAAIC,aACXF,QAAQC,IAAIE,OAAO,GAAGH,QAAQC,IAAIE,IAAI,YAAW,oBAAIC,KAAAA,GAAOC,YAAW,CAAA,SAAWC;AAErF,SAAOR;AACT;AAEO,IAAMS,iBAA+B1C,oBAAoB;EAC9DC,UAAUiC,eAAAA;EACVhC,QAAQ;IAACyC,SAASC;IAAOD,SAASE;IAAMF,SAASG;IAAMH,SAASI;;AAClE,CAAA;",
  "names": ["appendFileSync", "mkdirSync", "openSync", "dirname", "EAGAIN_MAX_DURATION", "createFileProcessor", "pathOrFd", "levels", "filters", "fd", "config", "entry", "length", "includes", "level", "shouldLog", "mkdirSync", "dirname", "openSync", "record", "message", "timestamp", "meta", "computedMeta", "context", "computedContext", "error", "computedError", "retryTS", "appendFileSync", "JSON", "stringify", "err", "code", "performance", "now", "console", "log", "logFilePath", "getLogFilePath", "process", "env", "LOG_FILE", "HOME", "Date", "toISOString", "undefined", "FILE_PROCESSOR", "LogLevel", "ERROR", "WARN", "INFO", "TRACE"]
}
