@mks2508/better-logger 0.18.2-alpha.2 → 0.18.4
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/Logger.d.ts +113 -21
- package/dist/Logger.d.ts.map +1 -1
- package/dist/ScopedLogger.d.ts +38 -1
- package/dist/ScopedLogger.d.ts.map +1 -1
- package/dist/chunks/LogContext-BO-f0KXu.js +142 -0
- package/dist/chunks/LogContext-BO-f0KXu.js.map +1 -0
- package/dist/chunks/{LogContext-BaMXleWj.cjs → LogContext-CIKxWPrK.cjs} +54 -12
- package/dist/chunks/LogContext-CIKxWPrK.cjs.map +1 -0
- package/dist/chunks/{transports-yK6CL0Ml.cjs → transports-BZ-Mc2IT.cjs} +196 -24
- package/dist/chunks/transports-BZ-Mc2IT.cjs.map +1 -0
- package/dist/chunks/{transports-BGfwwakw.js → transports-DvaLAeGJ.js} +191 -25
- package/dist/chunks/transports-DvaLAeGJ.js.map +1 -0
- package/dist/context/LogContext.d.ts +2 -4
- package/dist/context/LogContext.d.ts.map +1 -1
- package/dist/context.cjs +1 -1
- package/dist/context.js +1 -1
- package/dist/index.cjs +345 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +343 -35
- package/dist/index.js.map +1 -1
- package/dist/transports/OtlpTraceTransport.d.ts +118 -0
- package/dist/transports/OtlpTraceTransport.d.ts.map +1 -0
- package/dist/transports/OtlpTransport.d.ts +27 -1
- package/dist/transports/OtlpTransport.d.ts.map +1 -1
- package/dist/transports/SpanRuntime.d.ts +76 -0
- package/dist/transports/SpanRuntime.d.ts.map +1 -0
- package/dist/transports/TransportManager.d.ts +18 -11
- package/dist/transports/TransportManager.d.ts.map +1 -1
- package/dist/transports/index.d.ts +1 -0
- package/dist/transports/index.d.ts.map +1 -1
- package/dist/transports-module.d.ts +3 -1
- package/dist/transports-module.d.ts.map +1 -1
- package/dist/transports.cjs +2 -1
- package/dist/transports.js +2 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/transports.d.ts +121 -2
- package/dist/types/transports.d.ts.map +1 -1
- package/dist/utils/asyncLocalStorage.d.ts +33 -0
- package/dist/utils/asyncLocalStorage.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/chunks/LogContext-BaMXleWj.cjs.map +0 -1
- package/dist/chunks/LogContext-DjlITOzZ.js +0 -100
- package/dist/chunks/LogContext-DjlITOzZ.js.map +0 -1
- package/dist/chunks/transports-BGfwwakw.js.map +0 -1
- package/dist/chunks/transports-yK6CL0Ml.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -3,12 +3,12 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_core = require("./chunks/core-CqS_UBzJ.cjs");
|
|
6
|
-
const require_transports = require("./chunks/transports-
|
|
6
|
+
const require_transports = require("./chunks/transports-BZ-Mc2IT.cjs");
|
|
7
7
|
const require_utils = require("./chunks/utils-W_cxqriN.cjs");
|
|
8
8
|
const require_styling = require("./chunks/styling-Cel2wPRy.cjs");
|
|
9
9
|
const require_environment_detector = require("./chunks/environment-detector-D-tHkKWA.cjs");
|
|
10
10
|
const require_spinner = require("./chunks/spinner-BHyYEXsM.cjs");
|
|
11
|
-
const require_LogContext = require("./chunks/LogContext-
|
|
11
|
+
const require_LogContext = require("./chunks/LogContext-CIKxWPrK.cjs");
|
|
12
12
|
const require_HookBridge = require("./chunks/HookBridge-C-AvXmPD.cjs");
|
|
13
13
|
const require_SerializerBridge = require("./chunks/SerializerBridge-C4a9Z37F.cjs");
|
|
14
14
|
const require_server_fallback = require("./chunks/server-fallback-CaCPjWby.cjs");
|
|
@@ -293,6 +293,34 @@ var ScopedLogger = class {
|
|
|
293
293
|
this.parent.logWithBindings(this.getBindings(), "trace", ...args);
|
|
294
294
|
}
|
|
295
295
|
/**
|
|
296
|
+
* Emite un point-span con el scope de este logger como
|
|
297
|
+
* `SpanRecord.scope`. Ver {@link Logger.event}.
|
|
298
|
+
*
|
|
299
|
+
* @param {string} name - Nombre del evento.
|
|
300
|
+
* @param {SpanAttributes} [attributes] - Attributes del span.
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* logger.scope('BUILD').event('step.done', { step: 'compile' });
|
|
304
|
+
*/
|
|
305
|
+
event(name, attributes) {
|
|
306
|
+
this.parent._emitSpanEvent(name, attributes, this.getScopePrefix());
|
|
307
|
+
}
|
|
308
|
+
span(name, fnOrAttributes, maybeFn) {
|
|
309
|
+
const { attributes, fn } = resolveSpanArgs(fnOrAttributes, maybeFn);
|
|
310
|
+
return this.parent._runSpan(name, attributes, this.getScopePrefix(), fn);
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Inicia un span externally-ended etiquetado con el scope de este
|
|
314
|
+
* logger. Ver {@link Logger.startSpan}.
|
|
315
|
+
*
|
|
316
|
+
* @param {string} name - Nombre de la operación.
|
|
317
|
+
* @param {SpanAttributes} [attributes] - Attributes iniciales.
|
|
318
|
+
* @returns {Span} Handle con `set`/`end`/`fail`.
|
|
319
|
+
*/
|
|
320
|
+
startSpan(name, attributes) {
|
|
321
|
+
return this.parent._startSpan(name, attributes, this.getScopePrefix());
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
296
324
|
* Delegación a {@link Logger.step}: dibuja una barra de progreso discreta
|
|
297
325
|
* `current/total` para este scope.
|
|
298
326
|
*
|
|
@@ -1537,6 +1565,184 @@ function createTransportBridge() {
|
|
|
1537
1565
|
};
|
|
1538
1566
|
}
|
|
1539
1567
|
//#endregion
|
|
1568
|
+
//#region src/transports/SpanRuntime.ts
|
|
1569
|
+
/**
|
|
1570
|
+
* ALS singleton del módulo — compartido por todas las instancias de Logger.
|
|
1571
|
+
*
|
|
1572
|
+
* Resolución por capas (global → `process.getBuiltinModule` → `require`,
|
|
1573
|
+
* undefined en browser) delegada al helper compartido
|
|
1574
|
+
* {@link resolveAsyncLocalStorage} — ver su doc para el detalle de capas.
|
|
1575
|
+
* `context/LogContext.ts` usa el mismo helper para su ALS de MDC.
|
|
1576
|
+
*
|
|
1577
|
+
* Se crea lazy en el primer `runWithActiveSpan`: cargar `node:async_hooks`
|
|
1578
|
+
* cuesta ~2,2 MB de RSS en bun, y `getActiveSpan` se consulta en cada
|
|
1579
|
+
* dispatch de log — resolverlo al importar se lo cobraría a todo proceso
|
|
1580
|
+
* que loguea, use spans o no.
|
|
1581
|
+
*/
|
|
1582
|
+
let activeSpanStore;
|
|
1583
|
+
let spanStoreActivated = false;
|
|
1584
|
+
function activateSpanStore() {
|
|
1585
|
+
if (!spanStoreActivated) {
|
|
1586
|
+
spanStoreActivated = true;
|
|
1587
|
+
activeSpanStore = require_LogContext.resolveAsyncLocalStorage();
|
|
1588
|
+
}
|
|
1589
|
+
return activeSpanStore;
|
|
1590
|
+
}
|
|
1591
|
+
/**
|
|
1592
|
+
* Span activo en el call stack corriente (dentro de `span(fn)`), si lo hay.
|
|
1593
|
+
* Lo consumen la correlación log→span (`TransportRecord.traceId/spanId`) y la
|
|
1594
|
+
* resolución de `parentSpanId` en spans hijos.
|
|
1595
|
+
*
|
|
1596
|
+
* Sin `run()` previo el store estaría vacío igual, así que el guard por
|
|
1597
|
+
* flag es observable-identico a consultar el ALS real.
|
|
1598
|
+
*/
|
|
1599
|
+
function getActiveSpan() {
|
|
1600
|
+
if (!spanStoreActivated) return void 0;
|
|
1601
|
+
return activeSpanStore?.getStore();
|
|
1602
|
+
}
|
|
1603
|
+
/**
|
|
1604
|
+
* Ejecuta `fn` con `record` como span activo. Sin ALS disponible (browser),
|
|
1605
|
+
* ejecuta `fn` directamente — sin correlación pero funcional.
|
|
1606
|
+
*/
|
|
1607
|
+
function runWithActiveSpan(record, fn) {
|
|
1608
|
+
const store = activateSpanStore();
|
|
1609
|
+
return store ? store.run(record, fn) : fn();
|
|
1610
|
+
}
|
|
1611
|
+
/** Nanosegundos Unix actuales como string decimal (formato OTLP). */
|
|
1612
|
+
function nowUnixNano() {
|
|
1613
|
+
return String(BigInt(Date.now()) * 1000000n);
|
|
1614
|
+
}
|
|
1615
|
+
/**
|
|
1616
|
+
* Hex aleatorio de `bytes` bytes. Usa `crypto.getRandomValues`; sin
|
|
1617
|
+
* `crypto` (runtimes exóticos) degrada a `Math.random` — suficiente para ids
|
|
1618
|
+
* de correlación, no para secrets.
|
|
1619
|
+
*/
|
|
1620
|
+
function randomHex(bytes) {
|
|
1621
|
+
const cryptoObj = globalThis.crypto;
|
|
1622
|
+
if (cryptoObj?.getRandomValues) {
|
|
1623
|
+
const buf = new Uint8Array(bytes);
|
|
1624
|
+
cryptoObj.getRandomValues(buf);
|
|
1625
|
+
let out = "";
|
|
1626
|
+
for (const b of buf) out += b.toString(16).padStart(2, "0");
|
|
1627
|
+
return out;
|
|
1628
|
+
}
|
|
1629
|
+
let out = "";
|
|
1630
|
+
for (let i = 0; i < bytes * 2; i++) out += Math.floor(Math.random() * 16).toString(16);
|
|
1631
|
+
return out;
|
|
1632
|
+
}
|
|
1633
|
+
/** Trace id W3C: 16 bytes → 32 chars hex. */
|
|
1634
|
+
function generateTraceId() {
|
|
1635
|
+
return randomHex(16);
|
|
1636
|
+
}
|
|
1637
|
+
/** Span id W3C: 8 bytes → 16 chars hex. */
|
|
1638
|
+
function generateSpanId() {
|
|
1639
|
+
return randomHex(8);
|
|
1640
|
+
}
|
|
1641
|
+
/**
|
|
1642
|
+
* Registry de spans abiertos (leak-safety). Cubre tanto los de `startSpan()`
|
|
1643
|
+
* (externally-ended, el caso del handoff) como los de `span(fn)` en curso:
|
|
1644
|
+
* si un flush llega mid-flight, es mejor exportar el span incompleto que
|
|
1645
|
+
* tirarlo. El doble-`end()` es no-op, así que el cierre natural posterior no
|
|
1646
|
+
* duplica el export.
|
|
1647
|
+
*/
|
|
1648
|
+
const openSpans = /* @__PURE__ */ new Map();
|
|
1649
|
+
/**
|
|
1650
|
+
* Crea el record de span y su {@link Span} handle. El handle registra el
|
|
1651
|
+
* span en el registry de abiertos; `onEnd` se invoca una única vez, con el
|
|
1652
|
+
* record final (duración real o `incomplete: true`), para su export al
|
|
1653
|
+
* pipeline de transports.
|
|
1654
|
+
*
|
|
1655
|
+
* `end()` solo fija `endTimeUnixNano` si no se fijó antes — así los
|
|
1656
|
+
* point-spans (`event()`) pueden fijar `end = start` exacto.
|
|
1657
|
+
*
|
|
1658
|
+
* @param name - Nombre de la operación.
|
|
1659
|
+
* @param attributes - Attributes iniciales (copia propia del record).
|
|
1660
|
+
* @param scope - Scope del logger emisor.
|
|
1661
|
+
* @param onEnd - Callback de export; recibe el record cerrado.
|
|
1662
|
+
* @returns El record (para el ALS store) y el handle del span.
|
|
1663
|
+
*/
|
|
1664
|
+
function createSpan(name, attributes, scope, onEnd) {
|
|
1665
|
+
const parent = getActiveSpan();
|
|
1666
|
+
const record = {
|
|
1667
|
+
kind: "span",
|
|
1668
|
+
traceId: parent?.traceId ?? generateTraceId(),
|
|
1669
|
+
spanId: generateSpanId(),
|
|
1670
|
+
parentSpanId: parent?.spanId,
|
|
1671
|
+
name,
|
|
1672
|
+
spanKind: 1,
|
|
1673
|
+
startTimeUnixNano: nowUnixNano(),
|
|
1674
|
+
endTimeUnixNano: "0",
|
|
1675
|
+
attributes: { ...attributes ?? {} },
|
|
1676
|
+
scope
|
|
1677
|
+
};
|
|
1678
|
+
let ended = false;
|
|
1679
|
+
const finish = () => {
|
|
1680
|
+
if (ended) return;
|
|
1681
|
+
ended = true;
|
|
1682
|
+
openSpans.delete(record);
|
|
1683
|
+
onEnd(record);
|
|
1684
|
+
};
|
|
1685
|
+
openSpans.set(record, {
|
|
1686
|
+
record,
|
|
1687
|
+
end: finish,
|
|
1688
|
+
forceEnd: () => {
|
|
1689
|
+
if (ended) return;
|
|
1690
|
+
record.incomplete = true;
|
|
1691
|
+
if (record.endTimeUnixNano === "0") record.endTimeUnixNano = nowUnixNano();
|
|
1692
|
+
finish();
|
|
1693
|
+
}
|
|
1694
|
+
});
|
|
1695
|
+
const handle = {
|
|
1696
|
+
traceId: record.traceId,
|
|
1697
|
+
spanId: record.spanId,
|
|
1698
|
+
set(key, value) {
|
|
1699
|
+
record.attributes[key] = value;
|
|
1700
|
+
return handle;
|
|
1701
|
+
},
|
|
1702
|
+
end(attributes) {
|
|
1703
|
+
if (attributes) Object.assign(record.attributes, attributes);
|
|
1704
|
+
if (ended) return;
|
|
1705
|
+
if (record.endTimeUnixNano === "0") record.endTimeUnixNano = nowUnixNano();
|
|
1706
|
+
finish();
|
|
1707
|
+
},
|
|
1708
|
+
fail(err) {
|
|
1709
|
+
if (ended) return;
|
|
1710
|
+
record.status = {
|
|
1711
|
+
code: 2,
|
|
1712
|
+
message: err instanceof Error ? err.message : String(err)
|
|
1713
|
+
};
|
|
1714
|
+
this.end();
|
|
1715
|
+
}
|
|
1716
|
+
};
|
|
1717
|
+
return {
|
|
1718
|
+
record,
|
|
1719
|
+
span: handle
|
|
1720
|
+
};
|
|
1721
|
+
}
|
|
1722
|
+
/**
|
|
1723
|
+
* Emite un point-span (`event()`): start = end exactamente, sin registro en
|
|
1724
|
+
* abiertos tras el cierre — no hay leak posible. El `parentSpanId` se resuelve
|
|
1725
|
+
* contra el span activo si existe, pero NO fija contexto ALS.
|
|
1726
|
+
*/
|
|
1727
|
+
function emitEventSpan(name, attributes, scope, onEnd) {
|
|
1728
|
+
const { record, span } = createSpan(name, attributes, scope, onEnd);
|
|
1729
|
+
record.endTimeUnixNano = record.startTimeUnixNano;
|
|
1730
|
+
span.end();
|
|
1731
|
+
}
|
|
1732
|
+
/**
|
|
1733
|
+
* Fuerza el cierre de todos los spans abiertos (`incomplete: true`) y los
|
|
1734
|
+
* exporta vía el `onEnd` de cada uno. Lo invocan `flushTransports()` /
|
|
1735
|
+
* `closeTransports()` / `cleanup()` ANTES del flush real — un span abierto
|
|
1736
|
+
* nunca se tira en shutdown.
|
|
1737
|
+
*
|
|
1738
|
+
* @returns Los records forzados a cerrar (para diagnóstico/tests).
|
|
1739
|
+
*/
|
|
1740
|
+
function forceCloseOpenSpans() {
|
|
1741
|
+
const snapshot = [...openSpans.values()];
|
|
1742
|
+
for (const entry of snapshot) entry.forceEnd();
|
|
1743
|
+
return snapshot.map((entry) => entry.record);
|
|
1744
|
+
}
|
|
1745
|
+
//#endregion
|
|
1540
1746
|
//#region src/playground/TerminalBridge.ts
|
|
1541
1747
|
/**
|
|
1542
1748
|
* Crea un {@link TerminalBridge} usando un getter para evitar referencias
|
|
@@ -2012,6 +2218,7 @@ var Logger = class Logger {
|
|
|
2012
2218
|
} catch {}
|
|
2013
2219
|
this.themeChangeListener = null;
|
|
2014
2220
|
}
|
|
2221
|
+
forceCloseOpenSpans();
|
|
2015
2222
|
await this.transportBridge.closeTransports();
|
|
2016
2223
|
this.handlers.length = 0;
|
|
2017
2224
|
this.timers.clear();
|
|
@@ -2434,21 +2641,27 @@ var Logger = class Logger {
|
|
|
2434
2641
|
return this.transportBridge.removeTransport(id);
|
|
2435
2642
|
}
|
|
2436
2643
|
/**
|
|
2437
|
-
* Fuerza el flush de todos los transports
|
|
2644
|
+
* Fuerza el flush de todos los transports. Antes de flushear, cierra los
|
|
2645
|
+
* spans aún abiertos (`incomplete: true`) y los encola para export — un
|
|
2646
|
+
* span abierto nunca se tira en un flush.
|
|
2438
2647
|
*
|
|
2439
2648
|
* @returns Promise que resuelve cuando todos los buffers están vaciados
|
|
2440
2649
|
*
|
|
2441
2650
|
*/
|
|
2442
2651
|
async flushTransports() {
|
|
2652
|
+
forceCloseOpenSpans();
|
|
2443
2653
|
await this.transportBridge.flushTransports();
|
|
2444
2654
|
}
|
|
2445
2655
|
/**
|
|
2446
|
-
* Cierra todos los transports
|
|
2656
|
+
* Cierra todos los transports. Como en {@link flushTransports}, primero
|
|
2657
|
+
* fuerza el cierre de los spans abiertos para que viajen en el flush
|
|
2658
|
+
* final del close.
|
|
2447
2659
|
*
|
|
2448
2660
|
* @returns Promise que resuelve cuando todos están cerrados
|
|
2449
2661
|
*
|
|
2450
2662
|
*/
|
|
2451
2663
|
async closeTransports() {
|
|
2664
|
+
forceCloseOpenSpans();
|
|
2452
2665
|
await this.transportBridge.closeTransports();
|
|
2453
2666
|
}
|
|
2454
2667
|
/**
|
|
@@ -2477,36 +2690,6 @@ var Logger = class Logger {
|
|
|
2477
2690
|
* @internal
|
|
2478
2691
|
*/
|
|
2479
2692
|
_dispatchTag;
|
|
2480
|
-
/**
|
|
2481
|
-
* Computa el contexto completamente mergueado para este logger.
|
|
2482
|
-
*
|
|
2483
|
-
* La cadena de contexto se construye en el momento de crear el child:
|
|
2484
|
-
* cada child almacena el contexto fully-merged de su parent (en ese
|
|
2485
|
-
* instante) como `_parentContextRecord`. Esto implica que
|
|
2486
|
-
* `_parentContextRecord` ya contiene los bindings de todos los ancestros
|
|
2487
|
-
* en el orden de precedencia correcto (root primero, child más cercano al final).
|
|
2488
|
-
*
|
|
2489
|
-
* Orden de merge (gana el último):
|
|
2490
|
-
* 1. _parentContextRecord — snapshot del contexto mergueado del parent en la creación
|
|
2491
|
-
* 2. _bindings — bindings propios de este logger (llamadas a `child()`)
|
|
2492
|
-
* 3. ALS store — scope de `withContext`/`withContextAsync` (prioridad máxima)
|
|
2493
|
-
*
|
|
2494
|
-
* @internal
|
|
2495
|
-
* @returns El record de contexto mergueado
|
|
2496
|
-
*/
|
|
2497
|
-
_getMergedContext() {
|
|
2498
|
-
let merged = this._parentContextRecord ?? {};
|
|
2499
|
-
if (this._bindings && Object.keys(this._bindings).length > 0) merged = {
|
|
2500
|
-
...merged,
|
|
2501
|
-
...this._bindings
|
|
2502
|
-
};
|
|
2503
|
-
const alsContext = this.logContext._getAlsStore?.() ?? {};
|
|
2504
|
-
if (alsContext && Object.keys(alsContext).length > 0) merged = {
|
|
2505
|
-
...merged,
|
|
2506
|
-
...alsContext
|
|
2507
|
-
};
|
|
2508
|
-
return merged;
|
|
2509
|
-
}
|
|
2510
2693
|
/** @internal Expone el contexto base mergueado (sin ALS) a la closure de la child factory de LogContext. */
|
|
2511
2694
|
_captureMergedContext() {
|
|
2512
2695
|
let merged = this._parentContextRecord ?? {};
|
|
@@ -2550,6 +2733,11 @@ var Logger = class Logger {
|
|
|
2550
2733
|
resource: this.logContext._getResource() ? { ...this.logContext._getResource() } : void 0,
|
|
2551
2734
|
...extra
|
|
2552
2735
|
};
|
|
2736
|
+
const activeSpan = getActiveSpan();
|
|
2737
|
+
if (activeSpan && !record.traceId) {
|
|
2738
|
+
record.traceId = activeSpan.traceId;
|
|
2739
|
+
record.spanId = activeSpan.spanId;
|
|
2740
|
+
}
|
|
2553
2741
|
this.transportBridge.writeRecord(record);
|
|
2554
2742
|
}
|
|
2555
2743
|
/**
|
|
@@ -2806,6 +2994,104 @@ var Logger = class Logger {
|
|
|
2806
2994
|
return this.log("critical", ...args);
|
|
2807
2995
|
}
|
|
2808
2996
|
/**
|
|
2997
|
+
* Emite un **point-span**: un span con `start = end` para completion
|
|
2998
|
+
* signals y eventos puntuales (una operación instantánea, un hito).
|
|
2999
|
+
* No registra contexto activo ni puede leakear — se exporta de inmediato.
|
|
3000
|
+
*
|
|
3001
|
+
* El nombre `event` (y no `trace`) es deliberado: `trace` es un log level
|
|
3002
|
+
* (el -1) y está reservado.
|
|
3003
|
+
*
|
|
3004
|
+
* @param {string} name - Nombre del evento (`job.completed`, `cache.flushed`, ...).
|
|
3005
|
+
* @param {SpanAttributes} [attributes] - Attributes del span.
|
|
3006
|
+
*
|
|
3007
|
+
* @example
|
|
3008
|
+
* logger.event('build.finished', { status: 'ok', durationMs: 4200 });
|
|
3009
|
+
*
|
|
3010
|
+
* @see {@link span} para intervalos con work-block
|
|
3011
|
+
* @see {@link startSpan} para intervalos externally-ended
|
|
3012
|
+
*/
|
|
3013
|
+
event(name, attributes) {
|
|
3014
|
+
emitEventSpan(name, attributes, this._spanScopeName(), (record) => {
|
|
3015
|
+
this.transportBridge.writeRecord(record);
|
|
3016
|
+
});
|
|
3017
|
+
}
|
|
3018
|
+
span(name, fnOrAttributes, maybeFn) {
|
|
3019
|
+
const { attributes, fn } = resolveSpanArgs(fnOrAttributes, maybeFn);
|
|
3020
|
+
return this._runSpan(name, attributes, this._spanScopeName(), fn);
|
|
3021
|
+
}
|
|
3022
|
+
/**
|
|
3023
|
+
* Inicia un span de intervalo **externally-ended**: devuelve el handle y
|
|
3024
|
+
* NO fija contexto ALS (el cierre ocurre fuera del bloque léxico — p.ej.
|
|
3025
|
+
* un `cli.spawn` que se cierra desde un poll o callback externo).
|
|
3026
|
+
*
|
|
3027
|
+
* Si el span no se cierra antes de `flushTransports()` / shutdown, el
|
|
3028
|
+
* flush lo fuerza a cerrar con `incomplete: true` y lo exporta — nunca
|
|
3029
|
+
* se tira.
|
|
3030
|
+
*
|
|
3031
|
+
* @param {string} name - Nombre de la operación.
|
|
3032
|
+
* @param {SpanAttributes} [attributes] - Attributes iniciales.
|
|
3033
|
+
* @returns {Span} Handle con `set`/`end`/`fail` y los ids del span.
|
|
3034
|
+
*
|
|
3035
|
+
* @example
|
|
3036
|
+
* const s = logger.startSpan('spawn.build', { cmd: 'make' });
|
|
3037
|
+
* proc.on('exit', code => {
|
|
3038
|
+
* if (code === 0) s.end({ exitCode: code });
|
|
3039
|
+
* else s.fail(new Error(`exit ${code}`));
|
|
3040
|
+
* });
|
|
3041
|
+
*
|
|
3042
|
+
* @see {@link span} para el caso con work-block
|
|
3043
|
+
*/
|
|
3044
|
+
startSpan(name, attributes) {
|
|
3045
|
+
return this._startSpan(name, attributes, this._spanScopeName());
|
|
3046
|
+
}
|
|
3047
|
+
/**
|
|
3048
|
+
* Scope por defecto de los spans emitidos por este logger (el
|
|
3049
|
+
* `globalPrefix`, o `'root'`).
|
|
3050
|
+
* @internal
|
|
3051
|
+
*/
|
|
3052
|
+
_spanScopeName() {
|
|
3053
|
+
return this.config.globalPrefix || "root";
|
|
3054
|
+
}
|
|
3055
|
+
/**
|
|
3056
|
+
* Emite un point-span con scope explícito. Lo consume
|
|
3057
|
+
* {@link ScopedLogger.event}, que pasa su scope compuesto.
|
|
3058
|
+
* @internal
|
|
3059
|
+
*/
|
|
3060
|
+
_emitSpanEvent(name, attributes, scope) {
|
|
3061
|
+
emitEventSpan(name, attributes, scope, (record) => {
|
|
3062
|
+
this.transportBridge.writeRecord(record);
|
|
3063
|
+
});
|
|
3064
|
+
}
|
|
3065
|
+
/**
|
|
3066
|
+
* Crea un span externally-ended con scope explícito. Lo consume
|
|
3067
|
+
* {@link ScopedLogger.startSpan}.
|
|
3068
|
+
* @internal
|
|
3069
|
+
*/
|
|
3070
|
+
_startSpan(name, attributes, scope) {
|
|
3071
|
+
const { span } = createSpan(name, attributes, scope, (record) => {
|
|
3072
|
+
this.transportBridge.writeRecord(record);
|
|
3073
|
+
});
|
|
3074
|
+
return span;
|
|
3075
|
+
}
|
|
3076
|
+
/**
|
|
3077
|
+
* Corre `fn` dentro de un span activo en el ALS con scope explícito.
|
|
3078
|
+
* Lo consume {@link ScopedLogger.span}.
|
|
3079
|
+
* @internal
|
|
3080
|
+
*/
|
|
3081
|
+
async _runSpan(name, attributes, scope, fn) {
|
|
3082
|
+
const { record, span } = createSpan(name, attributes, scope, (r) => {
|
|
3083
|
+
this.transportBridge.writeRecord(r);
|
|
3084
|
+
});
|
|
3085
|
+
try {
|
|
3086
|
+
const result = await runWithActiveSpan(record, () => fn(span));
|
|
3087
|
+
span.end();
|
|
3088
|
+
return result;
|
|
3089
|
+
} catch (error) {
|
|
3090
|
+
span.fail(error);
|
|
3091
|
+
throw error;
|
|
3092
|
+
}
|
|
3093
|
+
}
|
|
3094
|
+
/**
|
|
2809
3095
|
* Muestra datos en formato de tabla. Pasa por la pipeline completa
|
|
2810
3096
|
* (outputMode-respecting writeOutput + transports + hooks).
|
|
2811
3097
|
*
|
|
@@ -3270,6 +3556,23 @@ function toAttributeValue(value) {
|
|
|
3270
3556
|
return;
|
|
3271
3557
|
}
|
|
3272
3558
|
}
|
|
3559
|
+
/**
|
|
3560
|
+
* Resuelve los argumentos del overload `span(name, fn?)` /
|
|
3561
|
+
* `span(name, attributes, fn)` a `{ attributes, fn }`.
|
|
3562
|
+
*
|
|
3563
|
+
* @internal Compartido con `ScopedLogger.span`; no es API pública.
|
|
3564
|
+
*/
|
|
3565
|
+
function resolveSpanArgs(fnOrAttributes, maybeFn) {
|
|
3566
|
+
if (typeof fnOrAttributes === "function") return {
|
|
3567
|
+
attributes: void 0,
|
|
3568
|
+
fn: fnOrAttributes
|
|
3569
|
+
};
|
|
3570
|
+
if (typeof maybeFn === "function") return {
|
|
3571
|
+
attributes: fnOrAttributes,
|
|
3572
|
+
fn: maybeFn
|
|
3573
|
+
};
|
|
3574
|
+
throw new TypeError("span(name, …): se requiere una función fn");
|
|
3575
|
+
}
|
|
3273
3576
|
//#endregion
|
|
3274
3577
|
//#region src/index.ts
|
|
3275
3578
|
/**
|
|
@@ -3302,6 +3605,11 @@ const group = (label, collapsed) => getLogger().group(label, collapsed);
|
|
|
3302
3605
|
const groupEnd = () => getLogger().groupEnd();
|
|
3303
3606
|
const time = (label) => getLogger().time(label);
|
|
3304
3607
|
const timeEnd = (label) => getLogger().timeEnd(label);
|
|
3608
|
+
const event = (name, attributes) => getLogger().event(name, attributes);
|
|
3609
|
+
const startSpan = (name, attributes) => getLogger().startSpan(name, attributes);
|
|
3610
|
+
function span(name, fnOrAttributes, maybeFn) {
|
|
3611
|
+
return getLogger().span(name, fnOrAttributes, maybeFn);
|
|
3612
|
+
}
|
|
3305
3613
|
const setGlobalPrefix = (prefix) => getLogger().setGlobalPrefix(prefix);
|
|
3306
3614
|
const scope = (name) => getLogger().scope(name);
|
|
3307
3615
|
const component = (name) => getLogger().component(name);
|
|
@@ -3360,6 +3668,7 @@ exports.critical = critical;
|
|
|
3360
3668
|
exports.debug = debug;
|
|
3361
3669
|
exports.default = src_default;
|
|
3362
3670
|
exports.error = error;
|
|
3671
|
+
exports.event = event;
|
|
3363
3672
|
exports.flushTransports = flushTransports;
|
|
3364
3673
|
exports.formatLogLevelANSI = require_utils.formatLogLevelANSI;
|
|
3365
3674
|
exports.formatSuccessANSI = require_utils.formatSuccessANSI;
|
|
@@ -3390,6 +3699,8 @@ exports.setGlobalPrefix = setGlobalPrefix;
|
|
|
3390
3699
|
exports.setTheme = setTheme;
|
|
3391
3700
|
exports.setVerbosity = setVerbosity;
|
|
3392
3701
|
exports.showBanner = showBanner;
|
|
3702
|
+
exports.span = span;
|
|
3703
|
+
exports.startSpan = startSpan;
|
|
3393
3704
|
exports.success = success;
|
|
3394
3705
|
exports.supportsANSI = require_environment_detector.supportsANSI;
|
|
3395
3706
|
exports.table = table;
|