@adaptic/utils 0.0.957 → 0.0.959
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +94 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +94 -1
- package/dist/index.mjs.map +1 -1
- package/dist/test.js +22 -1
- package/dist/test.js.map +1 -1
- package/dist/types/__tests__/logging.test.d.ts +2 -0
- package/dist/types/__tests__/logging.test.d.ts.map +1 -0
- package/dist/types/logger.d.ts +12 -0
- package/dist/types/logger.d.ts.map +1 -1
- package/dist/types/logging.d.ts +21 -1
- package/dist/types/logging.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -62,6 +62,7 @@ const defaultLogger = {
|
|
|
62
62
|
debug: (msg, ctx) => console.debug(msg, normalizeContext(ctx) || ""),
|
|
63
63
|
};
|
|
64
64
|
let currentLogger = defaultLogger;
|
|
65
|
+
let loggerInjected = false;
|
|
65
66
|
/**
|
|
66
67
|
* Sets a custom logger implementation.
|
|
67
68
|
* Call this to integrate with Pino or other logging libraries.
|
|
@@ -85,6 +86,21 @@ let currentLogger = defaultLogger;
|
|
|
85
86
|
*/
|
|
86
87
|
function setLogger(logger) {
|
|
87
88
|
currentLogger = logger;
|
|
89
|
+
loggerInjected = true;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Returns true when an external logger has been injected via {@link setLogger}.
|
|
93
|
+
*
|
|
94
|
+
* Used by the legacy {@link log} export in `logging.ts` to decide whether to
|
|
95
|
+
* route messages through the injected (production) logger or fall back to the
|
|
96
|
+
* `DisplayManager` terminal widget (standalone CLI usage). Without this flag,
|
|
97
|
+
* library code that imports `log` from `./logging` would silently bypass any
|
|
98
|
+
* structured logging pipeline (Pino, OTel) the host application has wired in.
|
|
99
|
+
*
|
|
100
|
+
* @returns `true` if {@link setLogger} has been called since the last reset
|
|
101
|
+
*/
|
|
102
|
+
function isLoggerInjected() {
|
|
103
|
+
return loggerInjected;
|
|
88
104
|
}
|
|
89
105
|
/**
|
|
90
106
|
* Gets the current logger instance.
|
|
@@ -112,6 +128,7 @@ function getLogger() {
|
|
|
112
128
|
*/
|
|
113
129
|
function resetLogger() {
|
|
114
130
|
currentLogger = defaultLogger;
|
|
131
|
+
loggerInjected = false;
|
|
115
132
|
}
|
|
116
133
|
|
|
117
134
|
/**
|
|
@@ -931,15 +948,91 @@ class DisplayManager {
|
|
|
931
948
|
}
|
|
932
949
|
|
|
933
950
|
/**
|
|
934
|
-
*
|
|
951
|
+
* LogType values that should map to a `Logger.info()` call when routed
|
|
952
|
+
* through an injected structured logger. Anything not in this set is
|
|
953
|
+
* treated as `info` (the safe default for unknown levels).
|
|
954
|
+
*/
|
|
955
|
+
const INFO_LEVEL_TYPES = new Set([
|
|
956
|
+
"info",
|
|
957
|
+
"major",
|
|
958
|
+
"table",
|
|
959
|
+
"system",
|
|
960
|
+
"cost",
|
|
961
|
+
]);
|
|
962
|
+
/**
|
|
963
|
+
* Builds the structured-logger context object for an injected logger call.
|
|
964
|
+
*
|
|
965
|
+
* The injected logger is expected to be a Pino-style structured logger
|
|
966
|
+
* (the engine wires it via `setUtilsLogger({...})` from
|
|
967
|
+
* `service-initializer.ts`). We surface every meaningful field from
|
|
968
|
+
* `LogOptions` so downstream consumers can filter, query, and correlate.
|
|
969
|
+
*/
|
|
970
|
+
function buildLoggerContext(options) {
|
|
971
|
+
const context = {};
|
|
972
|
+
if (options.source)
|
|
973
|
+
context.source = options.source;
|
|
974
|
+
if (options.account)
|
|
975
|
+
context.account = options.account;
|
|
976
|
+
if (options.symbol)
|
|
977
|
+
context.symbol = options.symbol;
|
|
978
|
+
if (options.type)
|
|
979
|
+
context.logType = options.type;
|
|
980
|
+
if (options.metadata)
|
|
981
|
+
Object.assign(context, options.metadata);
|
|
982
|
+
return context;
|
|
983
|
+
}
|
|
984
|
+
/**
|
|
985
|
+
* Logs a message.
|
|
986
|
+
*
|
|
987
|
+
* **Routing strategy:**
|
|
988
|
+
* 1. If a structured logger has been injected via `setLogger()` (the engine
|
|
989
|
+
* does this on startup with a Pino child logger), route the message
|
|
990
|
+
* through that logger so it joins the centralised logging pipeline with
|
|
991
|
+
* full structure, source attribution, correlation IDs, and downstream
|
|
992
|
+
* aggregation.
|
|
993
|
+
* 2. Otherwise (standalone CLI usage of `@adaptic/utils`), fall back to the
|
|
994
|
+
* legacy `DisplayManager`, which writes directly to `process.stdout` with
|
|
995
|
+
* ANSI colours, prompt preservation, and optional symbol-specific log
|
|
996
|
+
* files. This preserves backward compatibility for scripts.
|
|
997
|
+
*
|
|
998
|
+
* Without this routing, every Alpaca client call (positions, orders,
|
|
999
|
+
* streams, market-data, crypto, options — 28 modules) would silently
|
|
1000
|
+
* bypass the host application's structured logger and emit unstructured
|
|
1001
|
+
* lines straight to stdout, producing a long-running observability gap
|
|
1002
|
+
* in production deployments.
|
|
1003
|
+
*
|
|
935
1004
|
* @param message The message to log.
|
|
936
1005
|
* @param options Optional options.
|
|
937
1006
|
* @param options.source The source of the message.
|
|
938
1007
|
* @param options.type The type of message to log.
|
|
939
1008
|
* @param options.symbol The trading symbol associated with this log.
|
|
940
1009
|
* @param options.logToFile Force logging to a file even when no symbol is provided.
|
|
1010
|
+
* @param options.account Optional account identifier surfaced in logs.
|
|
1011
|
+
* @param options.metadata Additional structured fields to merge into context.
|
|
941
1012
|
*/
|
|
942
1013
|
function log$m(message, options = { source: "Server", type: "info" }) {
|
|
1014
|
+
if (isLoggerInjected()) {
|
|
1015
|
+
const logger = getLogger();
|
|
1016
|
+
const context = buildLoggerContext(options);
|
|
1017
|
+
const type = options.type ?? "info";
|
|
1018
|
+
if (type === "error") {
|
|
1019
|
+
logger.error(message, context);
|
|
1020
|
+
}
|
|
1021
|
+
else if (type === "warn") {
|
|
1022
|
+
logger.warn(message, context);
|
|
1023
|
+
}
|
|
1024
|
+
else if (type === "debug") {
|
|
1025
|
+
logger.debug(message, context);
|
|
1026
|
+
}
|
|
1027
|
+
else if (INFO_LEVEL_TYPES.has(type)) {
|
|
1028
|
+
logger.info(message, context);
|
|
1029
|
+
}
|
|
1030
|
+
else {
|
|
1031
|
+
logger.info(message, context);
|
|
1032
|
+
}
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
// Fallback: standalone CLI / no host logger wired in.
|
|
943
1036
|
const displayManager = DisplayManager.getInstance();
|
|
944
1037
|
displayManager.log(message, options);
|
|
945
1038
|
}
|