@statly/observe 1.0.0 → 1.2.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 CHANGED
@@ -12,6 +12,9 @@ Error tracking and monitoring for JavaScript and TypeScript applications. Captur
12
12
  ## Features
13
13
 
14
14
  - Automatic error capturing with stack traces
15
+ - **Structured Logging**: Production-grade logging with automatic scrubbing
16
+ - **Distributed Tracing**: Visualize function execution and call hierarchies
17
+ - **Performance Metrics**: Automated capture of latency and success rates
15
18
  - Breadcrumbs for debugging context
16
19
  - User context tracking
17
20
  - Release tracking
@@ -86,10 +89,148 @@ Statly.addBreadcrumb({
86
89
  level: 'info',
87
90
  });
88
91
 
89
- // Flush before exit (important for serverless)
92
+ # Flush before exit (important for serverless)
90
93
  await Statly.close();
91
94
  ```
92
95
 
96
+ ## Tracing & Performance
97
+
98
+ Statly Observe supports distributed tracing to help you visualize execution flow and measure backend performance.
99
+
100
+ ### Automatic Tracing
101
+
102
+ Use `Statly.trace()` to wrap functions. It works with both synchronous and asynchronous code:
103
+
104
+ ```typescript
105
+ import { Statly } from '@statly/observe';
106
+
107
+ const result = await Statly.trace('process_payment', async (span) => {
108
+ span.setTag('provider', 'stripe');
109
+
110
+ // Your logic here
111
+ const payment = await stripe.charges.create({...});
112
+
113
+ return payment;
114
+ });
115
+ ```
116
+
117
+ ### Manual Spans
118
+
119
+ For low-level control, you can start spans manually:
120
+
121
+ ```typescript
122
+ const span = Statly.startSpan('database_query');
123
+ try {
124
+ await db.query('...');
125
+ span.setTag('query_type', 'SELECT');
126
+ } finally {
127
+ span.finish(); // Reports to Statly
128
+ }
129
+ ```
130
+
131
+ ## Structured Logging
132
+
133
+ The Logger class provides production-grade structured logging with automatic secret scrubbing, session management, and batching.
134
+
135
+ ### Quick Start
136
+
137
+ ```typescript
138
+ import { Logger } from '@statly/observe';
139
+
140
+ const logger = Logger.create({
141
+ dsn: 'https://sk_live_xxx@statly.live/your-org',
142
+ environment: 'production',
143
+ loggerName: 'api-server',
144
+ });
145
+
146
+ // Log at different levels
147
+ logger.trace('Entering function', { args: [1, 2, 3] });
148
+ logger.debug('Processing request', { requestId: 'req_123' });
149
+ logger.info('User logged in', { userId: 'user_123' });
150
+ logger.warn('Rate limit approaching', { current: 95, limit: 100 });
151
+ logger.error('Payment failed', { orderId: 'ord_456', error: 'Card declined' });
152
+ logger.fatal('Database connection lost', { host: 'db.example.com' });
153
+ logger.audit('User role changed', { userId: 'user_123', newRole: 'admin' });
154
+
155
+ // Always close before exit
156
+ await logger.close();
157
+ ```
158
+
159
+ ### Child Loggers
160
+
161
+ Create child loggers with inherited context:
162
+
163
+ ```typescript
164
+ const requestLogger = logger.child({
165
+ context: { requestId: 'req_123' },
166
+ loggerName: 'request-handler',
167
+ });
168
+
169
+ requestLogger.info('Processing request'); // Includes requestId automatically
170
+ ```
171
+
172
+ ### User Context
173
+
174
+ Associate logs with users:
175
+
176
+ ```typescript
177
+ logger.setUser({
178
+ id: 'user_123',
179
+ email: 'jane@example.com',
180
+ name: 'Jane Doe',
181
+ });
182
+ ```
183
+
184
+ ### Secret Scrubbing
185
+
186
+ The logger automatically scrubs sensitive data (API keys, passwords, credit cards, etc.). Add custom patterns:
187
+
188
+ ```typescript
189
+ const logger = Logger.create({
190
+ dsn: '...',
191
+ scrubPatterns: [
192
+ /my-custom-secret-[a-z0-9]+/gi,
193
+ /internal-token-\d+/g,
194
+ ],
195
+ });
196
+ ```
197
+
198
+ ### Sample Rates
199
+
200
+ Control log volume with per-level sampling:
201
+
202
+ ```typescript
203
+ const logger = Logger.create({
204
+ dsn: '...',
205
+ sampleRates: {
206
+ trace: 0.01, // 1% of trace logs
207
+ debug: 0.1, // 10% of debug logs
208
+ info: 0.5, // 50% of info logs
209
+ warn: 1.0, // 100% of warnings
210
+ error: 1.0, // 100% of errors
211
+ fatal: 1.0, // 100% of fatal
212
+ },
213
+ });
214
+ ```
215
+
216
+ ### Logger Options
217
+
218
+ | Option | Type | Default | Description |
219
+ |--------|------|---------|-------------|
220
+ | `dsn` | `string` | required | Your project's Data Source Name |
221
+ | `environment` | `string` | `undefined` | Environment name |
222
+ | `release` | `string` | `undefined` | Release/version identifier |
223
+ | `loggerName` | `string` | `undefined` | Logger name for filtering |
224
+ | `sessionId` | `string` | auto-generated | Session ID for grouping logs |
225
+ | `user` | `object` | `undefined` | User context |
226
+ | `defaultContext` | `object` | `{}` | Default context for all logs |
227
+ | `minLevel` | `LogLevel` | `'trace'` | Minimum level to log |
228
+ | `sampleRates` | `object` | all 1.0 | Per-level sample rates |
229
+ | `scrubPatterns` | `RegExp[]` | `[]` | Additional patterns to scrub |
230
+ | `batchSize` | `number` | `50` | Batch size before flush |
231
+ | `flushInterval` | `number` | `5000` | Flush interval in ms |
232
+ | `maxQueueSize` | `number` | `1000` | Max queue size |
233
+
93
234
  ## Framework Integrations
94
235
 
95
236
  ### Express