@abbacchio/browser-transport 0.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 +220 -0
- package/dist/auto.d.ts +37 -0
- package/dist/auto.d.ts.map +1 -0
- package/dist/auto.js +41 -0
- package/dist/auto.js.map +1 -0
- package/dist/client.d.ts +74 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +132 -0
- package/dist/client.js.map +1 -0
- package/dist/console.d.ts +61 -0
- package/dist/console.d.ts.map +1 -0
- package/dist/console.js +257 -0
- package/dist/console.js.map +1 -0
- package/dist/crypto.d.ts +35 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +96 -0
- package/dist/crypto.js.map +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +98 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +126 -0
- package/dist/logger.js.map +1 -0
- package/dist/react/AbbacchioProvider.d.ts +83 -0
- package/dist/react/AbbacchioProvider.d.ts.map +1 -0
- package/dist/react/AbbacchioProvider.js +113 -0
- package/dist/react/AbbacchioProvider.js.map +1 -0
- package/dist/react/index.d.ts +5 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +5 -0
- package/dist/react/index.js.map +1 -0
- package/package.json +64 -0
package/README.md
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# @abbacchio/browser-transport
|
|
2
|
+
|
|
3
|
+
Browser and React logging client for Abbacchio. Intercept `console.log` and send structured logs to your Abbacchio log viewer.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @abbacchio/browser-transport
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @abbacchio/browser-transport
|
|
11
|
+
# or
|
|
12
|
+
yarn add @abbacchio/browser-transport
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
### Option 1: Auto-capture (one line)
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
import '@abbacchio/browser-transport/auto'
|
|
21
|
+
|
|
22
|
+
// All console.log calls now go to Abbacchio!
|
|
23
|
+
console.log('This is captured!')
|
|
24
|
+
console.error('Errors too!')
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Configure via global variable:
|
|
28
|
+
|
|
29
|
+
```html
|
|
30
|
+
<script>
|
|
31
|
+
window.__ABBACCHIO_CONFIG__ = {
|
|
32
|
+
url: 'http://localhost:4000/api/logs',
|
|
33
|
+
channel: 'my-app',
|
|
34
|
+
appName: 'my-web-app',
|
|
35
|
+
}
|
|
36
|
+
</script>
|
|
37
|
+
<script type="module">
|
|
38
|
+
import '@abbacchio/browser-transport/auto'
|
|
39
|
+
</script>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Option 2: Manual console interception
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
import { interceptConsole, stopInterceptConsole } from '@abbacchio/browser-transport'
|
|
46
|
+
|
|
47
|
+
// Start capturing
|
|
48
|
+
interceptConsole({
|
|
49
|
+
url: 'http://localhost:4000/api/logs',
|
|
50
|
+
channel: 'my-frontend',
|
|
51
|
+
appName: 'my-app',
|
|
52
|
+
secretKey: 'optional-encryption-key', // optional
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
// All console methods are now captured
|
|
56
|
+
console.log('Captured!')
|
|
57
|
+
console.warn('Warning captured!')
|
|
58
|
+
console.error('Error captured!')
|
|
59
|
+
|
|
60
|
+
// Stop capturing when done
|
|
61
|
+
stopInterceptConsole()
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Option 3: Structured Logger
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
import { createLogger } from '@abbacchio/browser-transport'
|
|
68
|
+
|
|
69
|
+
const log = createLogger({
|
|
70
|
+
url: 'http://localhost:4000/api/logs',
|
|
71
|
+
channel: 'my-app',
|
|
72
|
+
name: 'my-service',
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
log.info('User logged in', { userId: 123 })
|
|
76
|
+
log.warn('Rate limit approaching', { current: 95, max: 100 })
|
|
77
|
+
log.error('Failed to fetch', { endpoint: '/api/users', status: 500 })
|
|
78
|
+
|
|
79
|
+
// Create child logger with additional context
|
|
80
|
+
const requestLog = log.child({ requestId: 'abc-123' })
|
|
81
|
+
requestLog.info('Processing request')
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Option 4: React Provider
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import { AbbacchioProvider, useLogger } from '@abbacchio/browser-transport/react'
|
|
88
|
+
|
|
89
|
+
// Wrap your app
|
|
90
|
+
function App() {
|
|
91
|
+
return (
|
|
92
|
+
<AbbacchioProvider
|
|
93
|
+
url="http://localhost:4000/api/logs"
|
|
94
|
+
channel="my-react-app"
|
|
95
|
+
captureConsole // Optional: also capture console.log
|
|
96
|
+
>
|
|
97
|
+
<MyApp />
|
|
98
|
+
</AbbacchioProvider>
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Use in any component
|
|
103
|
+
function MyComponent() {
|
|
104
|
+
const log = useLogger()
|
|
105
|
+
|
|
106
|
+
const handleClick = () => {
|
|
107
|
+
log.info('Button clicked', { component: 'MyComponent' })
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return <button onClick={handleClick}>Click me</button>
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## API Reference
|
|
115
|
+
|
|
116
|
+
### `interceptConsole(options)`
|
|
117
|
+
|
|
118
|
+
Start intercepting console methods.
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
interface ConsoleInterceptorOptions {
|
|
122
|
+
url?: string // Server URL (default: 'http://localhost:4000/api/logs')
|
|
123
|
+
channel?: string // Channel name (default: 'default')
|
|
124
|
+
appName?: string // Logger name (default: 'browser')
|
|
125
|
+
secretKey?: string // Encryption key (optional)
|
|
126
|
+
batchSize?: number // Logs per batch (default: 10)
|
|
127
|
+
flushInterval?: number // Ms between flushes (default: 1000)
|
|
128
|
+
passthrough?: boolean // Still log to console (default: true)
|
|
129
|
+
includeUrl?: boolean // Include page URL (default: true)
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### `createLogger(options)`
|
|
134
|
+
|
|
135
|
+
Create a structured logger instance.
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
interface LoggerOptions {
|
|
139
|
+
url?: string
|
|
140
|
+
channel?: string
|
|
141
|
+
name?: string // Logger name/namespace
|
|
142
|
+
level?: number | 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal'
|
|
143
|
+
secretKey?: string
|
|
144
|
+
batchSize?: number
|
|
145
|
+
flushInterval?: number
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const log = createLogger(options)
|
|
149
|
+
|
|
150
|
+
log.trace(msg, data?)
|
|
151
|
+
log.debug(msg, data?)
|
|
152
|
+
log.info(msg, data?)
|
|
153
|
+
log.warn(msg, data?)
|
|
154
|
+
log.error(msg, data?)
|
|
155
|
+
log.fatal(msg, data?)
|
|
156
|
+
|
|
157
|
+
// Or with data first (Pino style)
|
|
158
|
+
log.info({ userId: 123 }, 'User action')
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### `AbbacchioProvider` (React)
|
|
162
|
+
|
|
163
|
+
React context provider for logging.
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
<AbbacchioProvider
|
|
167
|
+
url="..."
|
|
168
|
+
channel="..."
|
|
169
|
+
name="..."
|
|
170
|
+
captureConsole={true} // Also intercept console.log
|
|
171
|
+
>
|
|
172
|
+
{children}
|
|
173
|
+
</AbbacchioProvider>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### `useLogger()` / `useAbbacchio()` (React Hooks)
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
const log = useLogger() // Get logger instance
|
|
180
|
+
const { info, warn, error } = useAbbacchio() // Get logging methods
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Encryption
|
|
184
|
+
|
|
185
|
+
All options support optional end-to-end encryption:
|
|
186
|
+
|
|
187
|
+
```javascript
|
|
188
|
+
import { createLogger, generateKey } from '@abbacchio/browser-transport'
|
|
189
|
+
|
|
190
|
+
// Generate a key (do this once, store securely)
|
|
191
|
+
const key = generateKey()
|
|
192
|
+
console.log('Your key:', key)
|
|
193
|
+
|
|
194
|
+
// Use the key for encryption
|
|
195
|
+
const log = createLogger({
|
|
196
|
+
channel: 'my-app',
|
|
197
|
+
secretKey: key,
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
log.info('This is encrypted!')
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
The encrypted logs can only be decrypted in the Abbacchio dashboard by entering the same key.
|
|
204
|
+
|
|
205
|
+
## Log Levels
|
|
206
|
+
|
|
207
|
+
Compatible with Pino log levels:
|
|
208
|
+
|
|
209
|
+
| Level | Number |
|
|
210
|
+
|-------|--------|
|
|
211
|
+
| trace | 10 |
|
|
212
|
+
| debug | 20 |
|
|
213
|
+
| info | 30 |
|
|
214
|
+
| warn | 40 |
|
|
215
|
+
| error | 50 |
|
|
216
|
+
| fatal | 60 |
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
MIT
|
package/dist/auto.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-initialize console interception
|
|
3
|
+
*
|
|
4
|
+
* Simply import this module to start capturing console output:
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import '@abbacchio/browser-transport/auto'
|
|
9
|
+
*
|
|
10
|
+
* // All console.log calls now go to Abbacchio
|
|
11
|
+
* console.log('This is captured!')
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* Configuration can be done via window.__ABBACCHIO_CONFIG__:
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```html
|
|
18
|
+
* <script>
|
|
19
|
+
* window.__ABBACCHIO_CONFIG__ = {
|
|
20
|
+
* url: 'http://localhost:4000/api/logs',
|
|
21
|
+
* channel: 'my-app',
|
|
22
|
+
* appName: 'my-web-app',
|
|
23
|
+
* secretKey: 'optional-encryption-key',
|
|
24
|
+
* }
|
|
25
|
+
* </script>
|
|
26
|
+
* <script type="module">
|
|
27
|
+
* import '@abbacchio/browser-transport/auto'
|
|
28
|
+
* </script>
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
import { type ConsoleInterceptorOptions } from './console.js';
|
|
32
|
+
declare global {
|
|
33
|
+
interface Window {
|
|
34
|
+
__ABBACCHIO_CONFIG__?: ConsoleInterceptorOptions;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=auto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto.d.ts","sourceRoot":"","sources":["../src/auto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAoB,KAAK,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAGhF,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,oBAAoB,CAAC,EAAE,yBAAyB,CAAC;KAClD;CACF"}
|
package/dist/auto.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-initialize console interception
|
|
3
|
+
*
|
|
4
|
+
* Simply import this module to start capturing console output:
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import '@abbacchio/browser-transport/auto'
|
|
9
|
+
*
|
|
10
|
+
* // All console.log calls now go to Abbacchio
|
|
11
|
+
* console.log('This is captured!')
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* Configuration can be done via window.__ABBACCHIO_CONFIG__:
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```html
|
|
18
|
+
* <script>
|
|
19
|
+
* window.__ABBACCHIO_CONFIG__ = {
|
|
20
|
+
* url: 'http://localhost:4000/api/logs',
|
|
21
|
+
* channel: 'my-app',
|
|
22
|
+
* appName: 'my-web-app',
|
|
23
|
+
* secretKey: 'optional-encryption-key',
|
|
24
|
+
* }
|
|
25
|
+
* </script>
|
|
26
|
+
* <script type="module">
|
|
27
|
+
* import '@abbacchio/browser-transport/auto'
|
|
28
|
+
* </script>
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
import { interceptConsole } from './console.js';
|
|
32
|
+
// Get configuration from global variable or use defaults
|
|
33
|
+
const config = (typeof window !== 'undefined' && window.__ABBACCHIO_CONFIG__) || {};
|
|
34
|
+
// Start intercepting with merged config
|
|
35
|
+
interceptConsole({
|
|
36
|
+
url: 'http://localhost:4000/api/logs',
|
|
37
|
+
channel: 'browser',
|
|
38
|
+
appName: 'auto',
|
|
39
|
+
...config,
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=auto.js.map
|
package/dist/auto.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto.js","sourceRoot":"","sources":["../src/auto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,gBAAgB,EAAkC,MAAM,cAAc,CAAC;AAShF,yDAAyD;AACzD,MAAM,MAAM,GACV,CAAC,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC;AAEvE,wCAAwC;AACxC,gBAAgB,CAAC;IACf,GAAG,EAAE,gCAAgC;IACrC,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,MAAM;IACf,GAAG,MAAM;CACV,CAAC,CAAC"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser HTTP client for Abbacchio
|
|
3
|
+
* Handles batching, encryption, and sending logs to the server
|
|
4
|
+
*/
|
|
5
|
+
export interface AbbacchioClientOptions {
|
|
6
|
+
/** Server URL endpoint */
|
|
7
|
+
url?: string;
|
|
8
|
+
/** Secret key for encryption. If provided, logs will be encrypted before sending */
|
|
9
|
+
secretKey?: string;
|
|
10
|
+
/** Channel/app name for multi-app support. Defaults to 'default' */
|
|
11
|
+
channel?: string;
|
|
12
|
+
/** Number of logs to batch before sending. Defaults to 10 */
|
|
13
|
+
batchSize?: number;
|
|
14
|
+
/** Interval in ms between flushes. Defaults to 1000 */
|
|
15
|
+
flushInterval?: number;
|
|
16
|
+
/** Additional headers to send with requests */
|
|
17
|
+
headers?: Record<string, string>;
|
|
18
|
+
}
|
|
19
|
+
export interface LogEntry {
|
|
20
|
+
level: number;
|
|
21
|
+
time: number;
|
|
22
|
+
msg: string;
|
|
23
|
+
name?: string;
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Browser HTTP client for Abbacchio.
|
|
28
|
+
* Handles batching, encryption, and HTTP communication.
|
|
29
|
+
*/
|
|
30
|
+
export declare class AbbacchioClient {
|
|
31
|
+
private url;
|
|
32
|
+
private secretKey?;
|
|
33
|
+
private channel;
|
|
34
|
+
private batchSize;
|
|
35
|
+
private flushInterval;
|
|
36
|
+
private headers;
|
|
37
|
+
private buffer;
|
|
38
|
+
private timer;
|
|
39
|
+
private isClosed;
|
|
40
|
+
constructor(options?: AbbacchioClientOptions);
|
|
41
|
+
/**
|
|
42
|
+
* Process a log entry (encrypt if secretKey is provided)
|
|
43
|
+
*/
|
|
44
|
+
private processLog;
|
|
45
|
+
/**
|
|
46
|
+
* Add a log to the buffer and trigger send if needed
|
|
47
|
+
*/
|
|
48
|
+
add(log: LogEntry): void;
|
|
49
|
+
/**
|
|
50
|
+
* Schedule a send after the interval
|
|
51
|
+
*/
|
|
52
|
+
private scheduleSend;
|
|
53
|
+
/**
|
|
54
|
+
* Flush the buffer and send to server
|
|
55
|
+
*/
|
|
56
|
+
flush(): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Send logs to the Abbacchio server
|
|
59
|
+
*/
|
|
60
|
+
private sendToServer;
|
|
61
|
+
/**
|
|
62
|
+
* Close the client and flush any remaining logs
|
|
63
|
+
*/
|
|
64
|
+
close(): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Update client configuration
|
|
67
|
+
*/
|
|
68
|
+
configure(options: Partial<AbbacchioClientOptions>): void;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Create a new Abbacchio client instance
|
|
72
|
+
*/
|
|
73
|
+
export declare function createClient(options?: AbbacchioClientOptions): AbbacchioClient;
|
|
74
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,sBAAsB;IACrC,0BAA0B;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,OAAO,CAAyB;IAExC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,KAAK,CAA8C;IAC3D,OAAO,CAAC,QAAQ,CAAS;gBAEb,OAAO,GAAE,sBAA2B;IAehD;;OAEG;YACW,UAAU;IAOxB;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI;IAYxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAQpB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB5B;;OAEG;YACW,YAAY;IAiB1B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,sBAAsB,CAAC,GAAG,IAAI;CAQ1D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,eAAe,CAE9E"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser HTTP client for Abbacchio
|
|
3
|
+
* Handles batching, encryption, and sending logs to the server
|
|
4
|
+
*/
|
|
5
|
+
import { encrypt } from './crypto.js';
|
|
6
|
+
/**
|
|
7
|
+
* Browser HTTP client for Abbacchio.
|
|
8
|
+
* Handles batching, encryption, and HTTP communication.
|
|
9
|
+
*/
|
|
10
|
+
export class AbbacchioClient {
|
|
11
|
+
constructor(options = {}) {
|
|
12
|
+
this.buffer = [];
|
|
13
|
+
this.timer = null;
|
|
14
|
+
this.isClosed = false;
|
|
15
|
+
this.url = options.url || 'http://localhost:4000/api/logs';
|
|
16
|
+
this.secretKey = options.secretKey;
|
|
17
|
+
this.channel = options.channel || 'default';
|
|
18
|
+
this.batchSize = options.batchSize || 10;
|
|
19
|
+
this.flushInterval = options.flushInterval || 1000;
|
|
20
|
+
this.headers = options.headers || {};
|
|
21
|
+
// Flush on page unload
|
|
22
|
+
if (typeof window !== 'undefined') {
|
|
23
|
+
window.addEventListener('beforeunload', () => this.flush());
|
|
24
|
+
window.addEventListener('pagehide', () => this.flush());
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Process a log entry (encrypt if secretKey is provided)
|
|
29
|
+
*/
|
|
30
|
+
async processLog(log) {
|
|
31
|
+
if (this.secretKey) {
|
|
32
|
+
return { encrypted: await encrypt(JSON.stringify(log), this.secretKey) };
|
|
33
|
+
}
|
|
34
|
+
return log;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Add a log to the buffer and trigger send if needed
|
|
38
|
+
*/
|
|
39
|
+
add(log) {
|
|
40
|
+
if (this.isClosed)
|
|
41
|
+
return;
|
|
42
|
+
this.buffer.push(log);
|
|
43
|
+
if (this.buffer.length >= this.batchSize) {
|
|
44
|
+
this.flush();
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
this.scheduleSend();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Schedule a send after the interval
|
|
52
|
+
*/
|
|
53
|
+
scheduleSend() {
|
|
54
|
+
if (this.timer)
|
|
55
|
+
return;
|
|
56
|
+
this.timer = setTimeout(() => {
|
|
57
|
+
this.timer = null;
|
|
58
|
+
this.flush();
|
|
59
|
+
}, this.flushInterval);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Flush the buffer and send to server
|
|
63
|
+
*/
|
|
64
|
+
async flush() {
|
|
65
|
+
if (this.buffer.length === 0)
|
|
66
|
+
return;
|
|
67
|
+
const toSend = this.buffer;
|
|
68
|
+
this.buffer = [];
|
|
69
|
+
if (this.timer) {
|
|
70
|
+
clearTimeout(this.timer);
|
|
71
|
+
this.timer = null;
|
|
72
|
+
}
|
|
73
|
+
// Process logs (encrypt if needed)
|
|
74
|
+
const processedLogs = await Promise.all(toSend.map(log => this.processLog(log)));
|
|
75
|
+
await this.sendToServer(processedLogs);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Send logs to the Abbacchio server
|
|
79
|
+
*/
|
|
80
|
+
async sendToServer(logs) {
|
|
81
|
+
try {
|
|
82
|
+
await fetch(this.url, {
|
|
83
|
+
method: 'POST',
|
|
84
|
+
headers: {
|
|
85
|
+
'Content-Type': 'application/json',
|
|
86
|
+
'X-Encrypted': this.secretKey ? 'true' : 'false',
|
|
87
|
+
'X-Channel': this.channel,
|
|
88
|
+
...this.headers,
|
|
89
|
+
},
|
|
90
|
+
body: JSON.stringify({ logs }),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Silently fail - don't break the app if Abbacchio server is down
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Close the client and flush any remaining logs
|
|
99
|
+
*/
|
|
100
|
+
async close() {
|
|
101
|
+
this.isClosed = true;
|
|
102
|
+
if (this.timer) {
|
|
103
|
+
clearTimeout(this.timer);
|
|
104
|
+
this.timer = null;
|
|
105
|
+
}
|
|
106
|
+
await this.flush();
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Update client configuration
|
|
110
|
+
*/
|
|
111
|
+
configure(options) {
|
|
112
|
+
if (options.url !== undefined)
|
|
113
|
+
this.url = options.url;
|
|
114
|
+
if (options.secretKey !== undefined)
|
|
115
|
+
this.secretKey = options.secretKey;
|
|
116
|
+
if (options.channel !== undefined)
|
|
117
|
+
this.channel = options.channel;
|
|
118
|
+
if (options.batchSize !== undefined)
|
|
119
|
+
this.batchSize = options.batchSize;
|
|
120
|
+
if (options.flushInterval !== undefined)
|
|
121
|
+
this.flushInterval = options.flushInterval;
|
|
122
|
+
if (options.headers !== undefined)
|
|
123
|
+
this.headers = options.headers;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Create a new Abbacchio client instance
|
|
128
|
+
*/
|
|
129
|
+
export function createClient(options) {
|
|
130
|
+
return new AbbacchioClient(options);
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Console interceptor for Abbacchio
|
|
3
|
+
* Intercepts console.log, console.error, etc. and sends them to Abbacchio server
|
|
4
|
+
*/
|
|
5
|
+
import { type AbbacchioClientOptions } from './client.js';
|
|
6
|
+
export interface ConsoleInterceptorOptions extends AbbacchioClientOptions {
|
|
7
|
+
/** App name to use as the logger name. Defaults to 'browser' */
|
|
8
|
+
appName?: string;
|
|
9
|
+
/** Whether to still output to the original console. Defaults to true */
|
|
10
|
+
passthrough?: boolean;
|
|
11
|
+
/** Include the current URL in log data. Defaults to true */
|
|
12
|
+
includeUrl?: boolean;
|
|
13
|
+
/** Include the user agent in log data. Defaults to false */
|
|
14
|
+
includeUserAgent?: boolean;
|
|
15
|
+
/** Capture stack traces for log location. Defaults to false */
|
|
16
|
+
captureStackTrace?: boolean;
|
|
17
|
+
}
|
|
18
|
+
declare const originalConsole: {
|
|
19
|
+
log: {
|
|
20
|
+
(...data: any[]): void;
|
|
21
|
+
(message?: any, ...optionalParams: any[]): void;
|
|
22
|
+
};
|
|
23
|
+
info: {
|
|
24
|
+
(...data: any[]): void;
|
|
25
|
+
(message?: any, ...optionalParams: any[]): void;
|
|
26
|
+
};
|
|
27
|
+
warn: {
|
|
28
|
+
(...data: any[]): void;
|
|
29
|
+
(message?: any, ...optionalParams: any[]): void;
|
|
30
|
+
};
|
|
31
|
+
error: {
|
|
32
|
+
(...data: any[]): void;
|
|
33
|
+
(message?: any, ...optionalParams: any[]): void;
|
|
34
|
+
};
|
|
35
|
+
debug: {
|
|
36
|
+
(...data: any[]): void;
|
|
37
|
+
(message?: any, ...optionalParams: any[]): void;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Start intercepting console methods
|
|
42
|
+
*/
|
|
43
|
+
export declare function interceptConsole(opts?: ConsoleInterceptorOptions): void;
|
|
44
|
+
/**
|
|
45
|
+
* Stop intercepting console methods
|
|
46
|
+
*/
|
|
47
|
+
export declare function stopInterceptConsole(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Flush any buffered logs
|
|
50
|
+
*/
|
|
51
|
+
export declare function flushConsole(): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Check if console is currently being intercepted
|
|
54
|
+
*/
|
|
55
|
+
export declare function isConsoleIntercepted(): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Get the original console methods (for internal use when passthrough is false)
|
|
58
|
+
*/
|
|
59
|
+
export declare function getOriginalConsole(): typeof originalConsole;
|
|
60
|
+
export {};
|
|
61
|
+
//# sourceMappingURL=console.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../src/console.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAmB,KAAK,sBAAsB,EAAiB,MAAM,aAAa,CAAC;AAE1F,MAAM,WAAW,yBAA0B,SAAQ,sBAAsB;IACvE,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,+DAA+D;IAC/D,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAYD,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;CAMpB,CAAC;AAkMF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,yBAA8B,GAAG,IAAI,CAoB3E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAiB3C;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAIlD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,eAAe,CAE3D"}
|