@planetmoondrop/logger-client 2.1.0
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 +85 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +117 -0
- package/dist/storage.d.ts +30 -0
- package/dist/storage.js +78 -0
- package/dist/types.d.ts +48 -0
- package/dist/types.js +2 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# @planetmoondrop/logger-client
|
|
2
|
+
|
|
3
|
+
Axios interceptor for frontend apps that connects them to the `@planetmoondrop/centralized-logger` trace chain.
|
|
4
|
+
|
|
5
|
+
Reads the `x-loki-trace-id` response header from any API response and injects it back into every subsequent request — so your frontend sessions appear as a continuous trace in Grafana alongside the backend logs.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @planetmoondrop/logger-client axios
|
|
11
|
+
# or
|
|
12
|
+
pnpm add @planetmoondrop/logger-client axios
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Basic usage
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import axios from 'axios';
|
|
19
|
+
import { attachSessionInterceptor } from '@planetmoondrop/logger-client';
|
|
20
|
+
|
|
21
|
+
const api = axios.create({ baseURL: 'https://api.example.com' });
|
|
22
|
+
|
|
23
|
+
// Attach once at app startup.
|
|
24
|
+
// Returns both interceptor IDs so you can eject later if needed.
|
|
25
|
+
const { requestId, responseId } = attachSessionInterceptor(api);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
That's it. Every response that includes `x-loki-trace-id` stores the value, and every outgoing request includes it so the backend can correlate the call to an existing trace.
|
|
29
|
+
|
|
30
|
+
## Options
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
const ids = attachSessionInterceptor(api, {
|
|
34
|
+
// Response header to read the trace ID from
|
|
35
|
+
responseHeader: 'x-loki-trace-id', // default
|
|
36
|
+
|
|
37
|
+
// Request header to inject the trace ID into
|
|
38
|
+
requestHeader: 'x-loki-trace-id', // default
|
|
39
|
+
|
|
40
|
+
// Key used to store the trace ID in the storage backend
|
|
41
|
+
storageKey: 'sessionId', // default
|
|
42
|
+
|
|
43
|
+
// Custom storage — defaults to MemoryStorage (in-process Map).
|
|
44
|
+
// Provide any object that implements { getItem, setItem }.
|
|
45
|
+
storage: myStorage,
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Custom storage
|
|
50
|
+
|
|
51
|
+
The default `MemoryStorage` keeps the trace ID in a `Map` — it works fine for a single-page session but clears on page reload. Provide your own storage to persist across reloads:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { attachSessionInterceptor, SessionStorage } from '@planetmoondrop/logger-client';
|
|
55
|
+
|
|
56
|
+
// Browser localStorage
|
|
57
|
+
const webStorage: SessionStorage = {
|
|
58
|
+
getItem: (key) => localStorage.getItem(key),
|
|
59
|
+
setItem: (key, value) => localStorage.setItem(key, value),
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
attachSessionInterceptor(api, { storage: webStorage });
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
// React Native — AsyncStorage (async storage is fully supported)
|
|
67
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
68
|
+
|
|
69
|
+
attachSessionInterceptor(api, {
|
|
70
|
+
storage: {
|
|
71
|
+
getItem: (key) => AsyncStorage.getItem(key),
|
|
72
|
+
setItem: (key, value) => AsyncStorage.setItem(key, value),
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Ejecting
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
const { requestId, responseId } = attachSessionInterceptor(api);
|
|
81
|
+
|
|
82
|
+
// Remove both interceptors (e.g. on logout)
|
|
83
|
+
api.interceptors.request.eject(requestId);
|
|
84
|
+
api.interceptors.response.eject(responseId);
|
|
85
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { AxiosInstance } from 'axios';
|
|
2
|
+
import { SessionInterceptorOptions, SessionStorage } from './types';
|
|
3
|
+
import { MemoryStorage, BrowserSessionStorage, BrowserLocalStorage } from './storage';
|
|
4
|
+
export { MemoryStorage, BrowserSessionStorage, BrowserLocalStorage };
|
|
5
|
+
export type { SessionInterceptorOptions, SessionStorage };
|
|
6
|
+
/**
|
|
7
|
+
* IDs returned by `attachSessionInterceptor`, one per Axios interceptor slot.
|
|
8
|
+
* Pass them to `axiosInstance.interceptors.request.eject(requestId)` /
|
|
9
|
+
* `axiosInstance.interceptors.response.eject(responseId)` to detach.
|
|
10
|
+
*/
|
|
11
|
+
export interface SessionInterceptorIds {
|
|
12
|
+
/** ID of the request interceptor that injects the trace header. */
|
|
13
|
+
requestId: number;
|
|
14
|
+
/** ID of the response interceptor that captures the trace header. */
|
|
15
|
+
responseId: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Attaches request + response interceptors to the given Axios instance so that:
|
|
19
|
+
*
|
|
20
|
+
* - **Every response**: if the server returns `responseHeader`, the value is
|
|
21
|
+
* written into `storage` under `storageKey`.
|
|
22
|
+
* - **Every request**: if `storage` contains a value for `storageKey`, it is
|
|
23
|
+
* added to the request under `requestHeader`.
|
|
24
|
+
*
|
|
25
|
+
* Because MemoryStorage is cleared on page refresh, pass a `BrowserSessionStorage`
|
|
26
|
+
* or `BrowserLocalStorage` for production use so the trace context survives
|
|
27
|
+
* in-app navigations and full reloads.
|
|
28
|
+
*
|
|
29
|
+
* If `initialSessionId` is supplied (or auto-generated via `generateInitialId`),
|
|
30
|
+
* it is written to storage immediately so the **very first** outgoing request
|
|
31
|
+
* already carries a trace ID instead of waiting for the first response.
|
|
32
|
+
*
|
|
33
|
+
* @param axiosInstance - The Axios instance to instrument.
|
|
34
|
+
* @param options - Configuration options.
|
|
35
|
+
* @returns `{ requestId, responseId }` — Axios interceptor IDs for ejection.
|
|
36
|
+
*/
|
|
37
|
+
export declare function attachSessionInterceptor(axiosInstance: AxiosInstance, options?: SessionInterceptorOptions): SessionInterceptorIds;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.BrowserLocalStorage = exports.BrowserSessionStorage = exports.MemoryStorage = void 0;
|
|
13
|
+
exports.attachSessionInterceptor = attachSessionInterceptor;
|
|
14
|
+
const storage_1 = require("./storage");
|
|
15
|
+
Object.defineProperty(exports, "MemoryStorage", { enumerable: true, get: function () { return storage_1.MemoryStorage; } });
|
|
16
|
+
Object.defineProperty(exports, "BrowserSessionStorage", { enumerable: true, get: function () { return storage_1.BrowserSessionStorage; } });
|
|
17
|
+
Object.defineProperty(exports, "BrowserLocalStorage", { enumerable: true, get: function () { return storage_1.BrowserLocalStorage; } });
|
|
18
|
+
/**
|
|
19
|
+
* Attaches request + response interceptors to the given Axios instance so that:
|
|
20
|
+
*
|
|
21
|
+
* - **Every response**: if the server returns `responseHeader`, the value is
|
|
22
|
+
* written into `storage` under `storageKey`.
|
|
23
|
+
* - **Every request**: if `storage` contains a value for `storageKey`, it is
|
|
24
|
+
* added to the request under `requestHeader`.
|
|
25
|
+
*
|
|
26
|
+
* Because MemoryStorage is cleared on page refresh, pass a `BrowserSessionStorage`
|
|
27
|
+
* or `BrowserLocalStorage` for production use so the trace context survives
|
|
28
|
+
* in-app navigations and full reloads.
|
|
29
|
+
*
|
|
30
|
+
* If `initialSessionId` is supplied (or auto-generated via `generateInitialId`),
|
|
31
|
+
* it is written to storage immediately so the **very first** outgoing request
|
|
32
|
+
* already carries a trace ID instead of waiting for the first response.
|
|
33
|
+
*
|
|
34
|
+
* @param axiosInstance - The Axios instance to instrument.
|
|
35
|
+
* @param options - Configuration options.
|
|
36
|
+
* @returns `{ requestId, responseId }` — Axios interceptor IDs for ejection.
|
|
37
|
+
*/
|
|
38
|
+
function attachSessionInterceptor(axiosInstance, options = {}) {
|
|
39
|
+
const { responseHeader = 'x-loki-trace-id', requestHeader = 'x-loki-trace-id', storageKey = 'lokiTraceId', storage = new storage_1.MemoryStorage(), initialSessionId, generateInitialId = false, } = options;
|
|
40
|
+
// Seed storage so the first outgoing request already has a trace ID.
|
|
41
|
+
// IMPORTANT: only write if nothing is already stored — this ensures a page
|
|
42
|
+
// refresh within the same tab continues the same trace rather than resetting it.
|
|
43
|
+
// Priority: explicitly passed ID > auto-generated > nothing
|
|
44
|
+
void (() => __awaiter(this, void 0, void 0, function* () {
|
|
45
|
+
try {
|
|
46
|
+
const existing = yield storage.getItem(storageKey);
|
|
47
|
+
if (!existing) {
|
|
48
|
+
if (initialSessionId) {
|
|
49
|
+
yield storage.setItem(storageKey, initialSessionId);
|
|
50
|
+
}
|
|
51
|
+
else if (generateInitialId) {
|
|
52
|
+
yield storage.setItem(storageKey, generateHexId(32));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (_a) {
|
|
57
|
+
/* Silently ignore — storage errors must never break the app */
|
|
58
|
+
}
|
|
59
|
+
}))();
|
|
60
|
+
// Request interceptor: inject stored trace ID into outgoing headers
|
|
61
|
+
const requestId = axiosInstance.interceptors.request.use((config) => __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
try {
|
|
63
|
+
const traceId = yield storage.getItem(storageKey);
|
|
64
|
+
if (traceId) {
|
|
65
|
+
config.headers[requestHeader] = traceId;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
console.warn('[moondrop-logger-client] Failed to read trace ID:', err);
|
|
70
|
+
}
|
|
71
|
+
return config;
|
|
72
|
+
}), (error) => Promise.reject(error));
|
|
73
|
+
// Response interceptor: capture trace ID from response headers
|
|
74
|
+
const responseId = axiosInstance.interceptors.response.use((response) => __awaiter(this, void 0, void 0, function* () {
|
|
75
|
+
var _a;
|
|
76
|
+
const traceId = (_a = response.headers) === null || _a === void 0 ? void 0 : _a[responseHeader.toLowerCase()];
|
|
77
|
+
if (traceId && typeof traceId === 'string') {
|
|
78
|
+
try {
|
|
79
|
+
yield storage.setItem(storageKey, traceId);
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
console.warn('[moondrop-logger-client] Failed to save trace ID:', err);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return response;
|
|
86
|
+
}), (error) => __awaiter(this, void 0, void 0, function* () {
|
|
87
|
+
var _a, _b;
|
|
88
|
+
// Still attempt to capture the trace ID from error responses (4xx / 5xx)
|
|
89
|
+
const traceId = (_b = (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.headers) === null || _b === void 0 ? void 0 : _b[responseHeader.toLowerCase()];
|
|
90
|
+
if (traceId && typeof traceId === 'string') {
|
|
91
|
+
try {
|
|
92
|
+
yield storage.setItem(storageKey, traceId);
|
|
93
|
+
}
|
|
94
|
+
catch (_c) {
|
|
95
|
+
/* ignore */
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return Promise.reject(error);
|
|
99
|
+
}));
|
|
100
|
+
return { requestId, responseId };
|
|
101
|
+
}
|
|
102
|
+
/** Generates a random lowercase hex string of the requested character length. */
|
|
103
|
+
function generateHexId(length) {
|
|
104
|
+
const bytes = new Uint8Array(Math.ceil(length / 2));
|
|
105
|
+
if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
|
106
|
+
crypto.getRandomValues(bytes);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
// Node.js fallback (for SSR edge cases / tests)
|
|
110
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
111
|
+
bytes[i] = Math.floor(Math.random() * 256);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return Array.from(bytes, (b) => b.toString(16).padStart(2, '0'))
|
|
115
|
+
.join('')
|
|
116
|
+
.slice(0, length);
|
|
117
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { SessionStorage } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* In-memory storage (default).
|
|
4
|
+
* Data is lost when the page is refreshed — use BrowserSessionStorage or
|
|
5
|
+
* BrowserLocalStorage for persistence across navigations.
|
|
6
|
+
*/
|
|
7
|
+
export declare class MemoryStorage implements SessionStorage {
|
|
8
|
+
private store;
|
|
9
|
+
getItem(key: string): string | null;
|
|
10
|
+
setItem(key: string, value: string): void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* sessionStorage-backed storage.
|
|
14
|
+
* Data persists for the lifetime of the browser tab/session and survives
|
|
15
|
+
* in-app navigations (Next.js route changes, React Router, etc.).
|
|
16
|
+
* A new tab or page refresh after the session ends starts fresh.
|
|
17
|
+
*/
|
|
18
|
+
export declare class BrowserSessionStorage implements SessionStorage {
|
|
19
|
+
getItem(key: string): string | null;
|
|
20
|
+
setItem(key: string, value: string): void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* localStorage-backed storage.
|
|
24
|
+
* Data persists across page refreshes and across tabs for the same origin.
|
|
25
|
+
* Use when you want to correlate a user's activity across multiple visits.
|
|
26
|
+
*/
|
|
27
|
+
export declare class BrowserLocalStorage implements SessionStorage {
|
|
28
|
+
getItem(key: string): string | null;
|
|
29
|
+
setItem(key: string, value: string): void;
|
|
30
|
+
}
|
package/dist/storage.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BrowserLocalStorage = exports.BrowserSessionStorage = exports.MemoryStorage = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* In-memory storage (default).
|
|
6
|
+
* Data is lost when the page is refreshed — use BrowserSessionStorage or
|
|
7
|
+
* BrowserLocalStorage for persistence across navigations.
|
|
8
|
+
*/
|
|
9
|
+
class MemoryStorage {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.store = new Map();
|
|
12
|
+
}
|
|
13
|
+
getItem(key) {
|
|
14
|
+
var _a;
|
|
15
|
+
return (_a = this.store.get(key)) !== null && _a !== void 0 ? _a : null;
|
|
16
|
+
}
|
|
17
|
+
setItem(key, value) {
|
|
18
|
+
this.store.set(key, value);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.MemoryStorage = MemoryStorage;
|
|
22
|
+
/**
|
|
23
|
+
* sessionStorage-backed storage.
|
|
24
|
+
* Data persists for the lifetime of the browser tab/session and survives
|
|
25
|
+
* in-app navigations (Next.js route changes, React Router, etc.).
|
|
26
|
+
* A new tab or page refresh after the session ends starts fresh.
|
|
27
|
+
*/
|
|
28
|
+
class BrowserSessionStorage {
|
|
29
|
+
getItem(key) {
|
|
30
|
+
if (typeof window === 'undefined')
|
|
31
|
+
return null;
|
|
32
|
+
try {
|
|
33
|
+
return window.sessionStorage.getItem(key);
|
|
34
|
+
}
|
|
35
|
+
catch (_a) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
setItem(key, value) {
|
|
40
|
+
if (typeof window === 'undefined')
|
|
41
|
+
return;
|
|
42
|
+
try {
|
|
43
|
+
window.sessionStorage.setItem(key, value);
|
|
44
|
+
}
|
|
45
|
+
catch (_a) {
|
|
46
|
+
/* Silently ignore quota errors */
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.BrowserSessionStorage = BrowserSessionStorage;
|
|
51
|
+
/**
|
|
52
|
+
* localStorage-backed storage.
|
|
53
|
+
* Data persists across page refreshes and across tabs for the same origin.
|
|
54
|
+
* Use when you want to correlate a user's activity across multiple visits.
|
|
55
|
+
*/
|
|
56
|
+
class BrowserLocalStorage {
|
|
57
|
+
getItem(key) {
|
|
58
|
+
if (typeof window === 'undefined')
|
|
59
|
+
return null;
|
|
60
|
+
try {
|
|
61
|
+
return window.localStorage.getItem(key);
|
|
62
|
+
}
|
|
63
|
+
catch (_a) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
setItem(key, value) {
|
|
68
|
+
if (typeof window === 'undefined')
|
|
69
|
+
return;
|
|
70
|
+
try {
|
|
71
|
+
window.localStorage.setItem(key, value);
|
|
72
|
+
}
|
|
73
|
+
catch (_a) {
|
|
74
|
+
/* Silently ignore quota errors */
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.BrowserLocalStorage = BrowserLocalStorage;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage interface for saving/loading the trace session ID.
|
|
3
|
+
* Both synchronous and async implementations are accepted.
|
|
4
|
+
*/
|
|
5
|
+
export interface SessionStorage {
|
|
6
|
+
getItem(key: string): string | null | Promise<string | null>;
|
|
7
|
+
setItem(key: string, value: string): void | Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Options for `attachSessionInterceptor`.
|
|
11
|
+
*/
|
|
12
|
+
export interface SessionInterceptorOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Name of the response header to read the trace ID from.
|
|
15
|
+
* @default 'x-loki-trace-id'
|
|
16
|
+
*/
|
|
17
|
+
responseHeader?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Name of the request header to send the trace ID in.
|
|
20
|
+
* @default 'x-loki-trace-id'
|
|
21
|
+
*/
|
|
22
|
+
requestHeader?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Key used to store the trace ID in the storage backend.
|
|
25
|
+
* @default 'lokiTraceId'
|
|
26
|
+
*/
|
|
27
|
+
storageKey?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Storage backend.
|
|
30
|
+
* - `MemoryStorage` (default): ephemeral, cleared on page refresh.
|
|
31
|
+
* - `BrowserSessionStorage`: survives in-app navigation and reloads within the same tab.
|
|
32
|
+
* - `BrowserLocalStorage`: persists across tabs and full page refreshes.
|
|
33
|
+
*/
|
|
34
|
+
storage?: SessionStorage;
|
|
35
|
+
/**
|
|
36
|
+
* An explicit session / trace ID to seed into storage immediately on setup.
|
|
37
|
+
* This ensures the **first outgoing request** already carries a trace ID.
|
|
38
|
+
* Takes precedence over `generateInitialId`.
|
|
39
|
+
*/
|
|
40
|
+
initialSessionId?: string;
|
|
41
|
+
/**
|
|
42
|
+
* When `true`, a random 32-char hex trace ID is auto-generated and seeded
|
|
43
|
+
* into storage on setup so the first request is already correlated.
|
|
44
|
+
* Ignored if `initialSessionId` is provided.
|
|
45
|
+
* @default false
|
|
46
|
+
*/
|
|
47
|
+
generateInitialId?: boolean;
|
|
48
|
+
}
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@planetmoondrop/logger-client",
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "Axios interceptor to manage x-loki-trace-id header",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"keywords": [
|
|
11
|
+
"axios",
|
|
12
|
+
"interceptor",
|
|
13
|
+
"trace",
|
|
14
|
+
"trace-id",
|
|
15
|
+
"traceId",
|
|
16
|
+
"x-loki-trace-id",
|
|
17
|
+
"planetmoondrop interceptor",
|
|
18
|
+
"axios interceptor",
|
|
19
|
+
"planetmoondrop",
|
|
20
|
+
"logger-client",
|
|
21
|
+
"logger",
|
|
22
|
+
"observability",
|
|
23
|
+
"distributed-tracing",
|
|
24
|
+
"microservices",
|
|
25
|
+
"nestjs",
|
|
26
|
+
"nestjs-logger",
|
|
27
|
+
"nestjs-logger-client",
|
|
28
|
+
"nestjs-logger-client-axios",
|
|
29
|
+
"nestjs-logger-client-axios-interceptor",
|
|
30
|
+
"nestjs-logger-client-axios-interceptor-loki",
|
|
31
|
+
"nestjs-logger-client-axios-interceptor-loki-trace-id",
|
|
32
|
+
"nestjs-logger-client-axios-interceptor-loki-trace-id-header",
|
|
33
|
+
"nestjs-logger-client-axios-interceptor-loki-trace-id-header-x-loki-trace-id",
|
|
34
|
+
"nestjs-logger-client-axios-interceptor-loki-trace-id-header-x-loki-trace-id"
|
|
35
|
+
],
|
|
36
|
+
"author": "Planetmoondrop",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"axios": ">=0.21.0"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^20.0.0",
|
|
46
|
+
"axios": "^1.6.0",
|
|
47
|
+
"typescript": "^5.0.0"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "tsc"
|
|
51
|
+
}
|
|
52
|
+
}
|