@logbrew/sdk 0.1.33 → 0.1.35
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/README.md +25 -5
- package/browser-breadcrumbs.cjs +5 -3
- package/core.cjs +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -252,6 +252,24 @@ const response = await client.shutdown(transport);
|
|
|
252
252
|
console.error(JSON.stringify({ ok: true, status: response.statusCode, attempts: response.attempts, events: 6 }));
|
|
253
253
|
```
|
|
254
254
|
|
|
255
|
+
## Read Events Back
|
|
256
|
+
|
|
257
|
+
A successful send shows that LogBrew accepted the request. It does not show
|
|
258
|
+
that you can read the event. After your app sends one event, read it
|
|
259
|
+
back with a project read key:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
logbrew projects keys create "<project_id>" --kind read \
|
|
263
|
+
--ingest-key-file "$HOME/.logbrew/setup-check.read" --json
|
|
264
|
+
export LOGBREW_TOKEN="$(< "$HOME/.logbrew/setup-check.read")"
|
|
265
|
+
logbrew read logs --since 1h --json
|
|
266
|
+
logbrew issues --since 1h --json
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
A read key reads 1 project and cannot send telemetry. Run `unset LOGBREW_TOKEN`
|
|
270
|
+
when you finish. [Read your events back](https://docs.logbrew.co/guides/verify-setup)
|
|
271
|
+
covers key kinds, empty results, and how to revoke the key.
|
|
272
|
+
|
|
255
273
|
## Explicit Metrics
|
|
256
274
|
|
|
257
275
|
Use `client.metric()` when application code already knows the measurement name, value, unit, and aggregation shape. Metrics are queued like other events and are not collected automatically.
|
|
@@ -367,7 +385,7 @@ If your app already owns an OpenTelemetry provider, `createLogBrewOpenTelemetryS
|
|
|
367
385
|
|
|
368
386
|
```js
|
|
369
387
|
import { SpanKind } from "@opentelemetry/api";
|
|
370
|
-
import {
|
|
388
|
+
import { TracerProvider } from "@opentelemetry/sdk-trace";
|
|
371
389
|
import {
|
|
372
390
|
createLogBrewOpenTelemetrySpanProcessor,
|
|
373
391
|
LogBrewClient,
|
|
@@ -387,7 +405,7 @@ const processor = createLogBrewOpenTelemetrySpanProcessor({
|
|
|
387
405
|
linkAttributeKeys: ["messaging.operation.name"],
|
|
388
406
|
metadata: { release: "checkout@1.2.3", environment: "production" }
|
|
389
407
|
});
|
|
390
|
-
const provider = new
|
|
408
|
+
const provider = new TracerProvider({ spanProcessors: [processor] });
|
|
391
409
|
const tracer = provider.getTracer("checkout-api");
|
|
392
410
|
|
|
393
411
|
const span = tracer.startSpan("GET /orders/:id", {
|
|
@@ -407,7 +425,7 @@ await processor.forceFlush();
|
|
|
407
425
|
If your OpenTelemetry setup already uses standard processors such as `SimpleSpanProcessor` or `BatchSpanProcessor`, use `createLogBrewOpenTelemetrySpanExporter()` instead:
|
|
408
426
|
|
|
409
427
|
```js
|
|
410
|
-
import {
|
|
428
|
+
import { TracerProvider, SimpleSpanProcessor } from "@opentelemetry/sdk-trace";
|
|
411
429
|
import {
|
|
412
430
|
createLogBrewOpenTelemetrySpanExporter,
|
|
413
431
|
LogBrewClient,
|
|
@@ -425,11 +443,13 @@ const exporter = createLogBrewOpenTelemetrySpanExporter({
|
|
|
425
443
|
includeTraceSummary: true,
|
|
426
444
|
metadata: { release: "checkout@1.2.3", environment: "production" }
|
|
427
445
|
});
|
|
428
|
-
const provider = new
|
|
429
|
-
spanProcessors: [new SimpleSpanProcessor(exporter)]
|
|
446
|
+
const provider = new TracerProvider({
|
|
447
|
+
spanProcessors: [new SimpleSpanProcessor({ exporter })]
|
|
430
448
|
});
|
|
431
449
|
```
|
|
432
450
|
|
|
451
|
+
These examples use `@opentelemetry/sdk-trace` 3. With `@opentelemetry/sdk-trace-base` 2, use `BasicTracerProvider` and `new SimpleSpanProcessor(exporter)`; the LogBrew processor and exporter work the same with both.
|
|
452
|
+
|
|
433
453
|
The OTel processor and exporter follow normal OTel sampled-span behavior by default and summarize up to eight span events and eight links. Set `includeTraceSummary: true` when you also want one synthetic `opentelemetry.trace:<root-name>` span per trace on processor `forceFlush()`/`shutdown()` or exporter `export()`/`forceFlush()`/`shutdown()`; the summary carries the trace ID, span count, error count, root span ID/name/kind, duration, and safe service/environment/route metadata so a batch reads like one request or transaction. They copy only a small safe default set such as service, environment, route, method, status code, span kind, instrumentation scope, exception type, exception event count, escaped exception count, and dropped-count metadata. Exception counts scan the readable span's events, while emitted exception type lists stay bounded. Escaped exception events on unset-status spans mark the LogBrew span as `error`; explicit OTel `OK` status stays `ok`. Additional event/link/span/resource attributes require explicit allowlists, and high-risk keys such as full URLs, headers, query strings, payloads, cookies, private auth values, DB statements, exception messages, and stacks stay blocked. Concurrent flush calls use one active send and one coalesced trailing drain: later spans leave the queue before their caller completes, while a failed active send consumes no extra retry budget. These helpers do not add an OpenTelemetry dependency, patch clients, own tracer providers, serialize baggage or tracestate, copy raw propagation headers, or capture request/response bodies.
|
|
434
454
|
|
|
435
455
|
LogBrew severity categories are `info`, `warning`, `error`, and `critical`. The JavaScript SDK accepts common runtime aliases such as `trace`, `debug`, `warn`, and `fatal` for compatibility, then serializes canonical values before queued events are sent. The shared mapping is documented in the [LogBrew severity contract](../../docs/severity-contract.md).
|
package/browser-breadcrumbs.cjs
CHANGED
|
@@ -49,6 +49,7 @@ function patchConsole(target, add) {
|
|
|
49
49
|
return [];
|
|
50
50
|
}
|
|
51
51
|
return Object.entries(CONSOLE_LEVELS).flatMap(([method, level]) => replaceMethod(target, method, (original) => (
|
|
52
|
+
/** @this {Console} */
|
|
52
53
|
function logBrewConsoleBreadcrumb(...args) {
|
|
53
54
|
const message = boundedText(consoleTemplate(args), MAX_MESSAGE_LENGTH);
|
|
54
55
|
if (message) {
|
|
@@ -60,7 +61,7 @@ function patchConsole(target, add) {
|
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
function patchFetch(browserWindow, add, ignored) {
|
|
63
|
-
return replaceMethod(browserWindow, "fetch", (original) => async function logBrewFetchBreadcrumb(input, init) {
|
|
64
|
+
return replaceMethod(browserWindow, "fetch", (original) => /** @this {*} */ async function logBrewFetchBreadcrumb(input, init) {
|
|
64
65
|
const method = String(init?.method ?? input?.method ?? "GET").toUpperCase();
|
|
65
66
|
const url = sanitizeUrl(typeof input === "string" || input instanceof URL ? input : input?.url, browserWindow);
|
|
66
67
|
try {
|
|
@@ -85,11 +86,11 @@ function patchXhr(browserWindow, add, ignored) {
|
|
|
85
86
|
}
|
|
86
87
|
const state = new WeakMap();
|
|
87
88
|
return [
|
|
88
|
-
...replaceMethod(prototype, "open", (original) => function logBrewXhrOpen(method, url, ...rest) {
|
|
89
|
+
...replaceMethod(prototype, "open", (original) => /** @this {XMLHttpRequest} */ function logBrewXhrOpen(method, url, ...rest) {
|
|
89
90
|
state.set(this, { method: String(method ?? "GET").toUpperCase(), url: sanitizeUrl(url, browserWindow) });
|
|
90
91
|
return original.call(this, method, url, ...rest);
|
|
91
92
|
}),
|
|
92
|
-
...replaceMethod(prototype, "send", (original) => function logBrewXhrSend(...args) {
|
|
93
|
+
...replaceMethod(prototype, "send", (original) => /** @this {XMLHttpRequest} */ function logBrewXhrSend(...args) {
|
|
93
94
|
const request = state.get(this);
|
|
94
95
|
if (request && !ignored.has(request.url) && typeof this.addEventListener === "function") {
|
|
95
96
|
this.addEventListener("loadend", () => {
|
|
@@ -115,6 +116,7 @@ function patchNavigation(browserWindow, add) {
|
|
|
115
116
|
}
|
|
116
117
|
};
|
|
117
118
|
const restores = ["pushState", "replaceState"].flatMap((method) => replaceMethod(history, method, (original) => (
|
|
119
|
+
/** @this {History} */
|
|
118
120
|
function logBrewNavigationBreadcrumb(...args) {
|
|
119
121
|
const result = original.apply(this, args);
|
|
120
122
|
record();
|
package/core.cjs
CHANGED
|
@@ -1595,6 +1595,7 @@ function installLogBrewConsoleCapture(config) {
|
|
|
1595
1595
|
}
|
|
1596
1596
|
|
|
1597
1597
|
function createConsoleCaptureMethod(config) {
|
|
1598
|
+
/** @this {*} */
|
|
1598
1599
|
return function logBrewConsoleMethod(...args) {
|
|
1599
1600
|
config.original.apply(this, args);
|
|
1600
1601
|
if (!config.state.installed) {
|