syntropylog 0.7.4 β 0.8.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 +729 -397
- package/dist/brokers/index.d.ts +7 -0
- package/dist/config.schema.js +8 -9
- package/dist/config.schema.js.map +1 -1
- package/dist/http/index.d.ts +7 -0
- package/dist/index.cjs +213 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +14 -21
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +211 -24
- package/dist/index.mjs.map +1 -1
- package/dist/logger/Logger.js +15 -4
- package/dist/logger/Logger.js.map +1 -1
- package/dist/logger/LoggerFactory.js +21 -9
- package/dist/logger/LoggerFactory.js.map +1 -1
- package/dist/logger/adapters/UniversalAdapter.js +30 -0
- package/dist/logger/adapters/UniversalAdapter.js.map +1 -0
- package/dist/logger/formatters/UniversalLogFormatter.js +81 -0
- package/dist/logger/formatters/UniversalLogFormatter.js.map +1 -0
- package/dist/logger/levels.js +1 -0
- package/dist/logger/levels.js.map +1 -1
- package/dist/logger/transports/AdapterTransport.js +55 -0
- package/dist/logger/transports/AdapterTransport.js.map +1 -0
- package/dist/logger/transports/ClassicConsoleTransport.js +3 -2
- package/dist/logger/transports/ClassicConsoleTransport.js.map +1 -1
- package/dist/logger/transports/CompactConsoleTransport.js +1 -0
- package/dist/logger/transports/CompactConsoleTransport.js.map +1 -1
- package/dist/logger/transports/PrettyConsoleTransport.js +1 -0
- package/dist/logger/transports/PrettyConsoleTransport.js.map +1 -1
- package/dist/logger/transports/adapter.types.js +2 -0
- package/dist/logger/transports/adapter.types.js.map +1 -0
- package/dist/redis/BeaconRedisMock.js +1 -0
- package/dist/redis/BeaconRedisMock.js.map +1 -1
- package/dist/serialization/pipeline/SerializationStep.js +5 -5
- package/dist/serialization/pipeline/SerializationStep.js.map +1 -1
- package/dist/testing/index.cjs +1 -0
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.mjs +1 -0
- package/dist/testing/index.mjs.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/config.schema.d.ts +7 -21
- package/dist/types/index.d.ts +3 -0
- package/dist/types/logger/ILogger.d.ts +6 -0
- package/dist/types/logger/Logger.d.ts +5 -0
- package/dist/types/logger/LoggerFactory.d.ts +1 -1
- package/dist/types/logger/adapters/UniversalAdapter.d.ts +22 -0
- package/dist/types/logger/formatters/UniversalLogFormatter.d.ts +32 -0
- package/dist/types/logger/levels.d.ts +1 -0
- package/dist/types/logger/transports/AdapterTransport.d.ts +48 -0
- package/dist/types/logger/transports/adapter.types.d.ts +28 -0
- package/package.json +64 -13
- package/dist/cli/audit.js +0 -58
- package/dist/cli/audit.js.map +0 -1
- package/dist/cli/checks.js +0 -164
- package/dist/cli/checks.js.map +0 -1
- package/dist/cli/cli.js +0 -112
- package/dist/cli/cli.js.map +0 -1
- package/dist/cli/doctor.js +0 -125
- package/dist/cli/doctor.js.map +0 -1
- package/dist/cli/init.js +0 -131
- package/dist/cli/init.js.map +0 -1
- package/dist/cli/templates.js +0 -91
- package/dist/cli/templates.js.map +0 -1
- package/dist/doctor.cjs +0 -140
- package/dist/doctor.cjs.map +0 -1
- package/dist/doctor.js +0 -23
- package/dist/doctor.js.map +0 -1
- package/dist/doctor.mjs +0 -138
- package/dist/doctor.mjs.map +0 -1
- package/dist/types/cli/audit.d.ts +0 -6
- package/dist/types/cli/checks.d.ts +0 -47
- package/dist/types/cli/cli.d.ts +0 -2
- package/dist/types/cli/doctor.d.ts +0 -29
- package/dist/types/cli/init.d.ts +0 -22
- package/dist/types/cli/templates.d.ts +0 -20
- package/dist/types/doctor.d.ts +0 -27
package/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# SyntropyLog
|
|
2
|
+
|
|
1
3
|
<p align="center">
|
|
2
4
|
<img src="./assets/beaconLog-2.png" alt="SyntropyLog Logo" width="170"/>
|
|
3
5
|
</p>
|
|
@@ -7,86 +9,75 @@
|
|
|
7
9
|
<p align="center">
|
|
8
10
|
<strong>From Chaos to Clarity</strong>
|
|
9
11
|
<br />
|
|
10
|
-
The Observability
|
|
12
|
+
The Instance Manager with Observability for High-Performance Teams
|
|
11
13
|
</p>
|
|
12
14
|
|
|
13
15
|
<p align="center">
|
|
14
16
|
<a href="https://www.npmjs.com/package/syntropylog"><img src="https://img.shields.io/npm/v/syntropylog.svg" alt="NPM Version"></a>
|
|
15
17
|
<a href="https://github.com/Syntropysoft/SyntropyLog/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/syntropylog.svg" alt="License"></a>
|
|
16
18
|
<a href="#"><img src="https://img.shields.io/badge/coverage-88.93%25-brightgreen" alt="Test Coverage"></a>
|
|
17
|
-
<a href="#"><img src="https://img.shields.io/badge/status-
|
|
19
|
+
<a href="#"><img src="https://img.shields.io/badge/status-rc_1-orange.svg" alt="RC 1"></a>
|
|
18
20
|
<a href="https://github.com/Syntropysoft/SyntropyLog/actions/workflows/codeql.yml"><img src="https://github.com/Syntropysoft/SyntropyLog/workflows/CodeQL/badge.svg" alt="CodeQL"></a>
|
|
19
21
|
<a href="https://github.com/Syntropysoft/SyntropyLog/security/advisories"><img src="https://img.shields.io/badge/dependabot-enabled-brightgreen.svg" alt="Dependabot"></a>
|
|
20
22
|
</p>
|
|
21
23
|
|
|
22
24
|
---
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
**We invite any member of the community to audit the code. If you find anything suspicious, please open an issue or a pull request.
|
|
27
|
-
We take security and transparency very seriously.**
|
|
26
|
+
## π What's New in v0.8.0
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
- No hidden telemetry, tracking, or obfuscated code.
|
|
31
|
-
- Automated dependency and vulnerability scans via GitHub Dependabot and CodeQL.
|
|
32
|
-
- High code coverage and comprehensive testing.
|
|
33
|
-
- External and community audits are welcome.
|
|
28
|
+
The **Universal Persistence Update** simplifies how developers connect SyntropyLog to any database without external adapters.
|
|
34
29
|
|
|
35
|
-
|
|
30
|
+
- **π Universal Persistence**: Use `UniversalAdapter` + `UniversalLogFormatter` to map logs to any schema (SQL/NoSQL) using pure JSON mapping.
|
|
31
|
+
- **π‘οΈ First-Class Audit Level**: A new `audit()` method designed for compliance and long-term storage, bypassing standard severity filters.
|
|
32
|
+
- **π¨ Enhanced Console UI**: Beautifully colorized output for the `audit` level across all console transports.
|
|
36
33
|
|
|
37
34
|
---
|
|
38
35
|
|
|
36
|
+
|
|
39
37
|
## π Table of Contents
|
|
40
38
|
|
|
41
|
-
- [
|
|
42
|
-
- [π Quick Start](#-quick-start)
|
|
39
|
+
- [π― What is SyntropyLog?](#-what-is-syntropylog)
|
|
40
|
+
- [π Quick Start (30 seconds)](#-quick-start-30-seconds)
|
|
41
|
+
- [π’ Enterprise Implementation Guide](#-enterprise-implementation-guide)
|
|
42
|
+
- [π Manual & Tutorials](#-manual--tutorials)
|
|
43
43
|
- [β¨ Key Features](#-key-features)
|
|
44
|
-
- [π Performance
|
|
45
|
-
- [π The Double Victory: Benchmark Evidence](#-the-double-victory-benchmark-evidence)
|
|
46
|
-
- [π Victory #1: Zero Overhead Core](#-victory-1-zero-overhead-core)
|
|
47
|
-
- [π― Victory #2: Intelligent Tree-Shaking](#-victory-2-intelligent-tree-shaking)
|
|
48
|
-
- [ποΈ Beyond a Logger: An Orchestration Framework](#οΈ-beyond-a-logger-an-orchestration-framework)
|
|
49
|
-
- [π― Positioning \& Final Verdict](#-positioning--final-verdict)
|
|
44
|
+
- [π Performance & Benchmarks](#-performance--benchmarks)
|
|
50
45
|
- [π Core Philosophy: Silent Observer](#-core-philosophy-silent-observer)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
- [
|
|
55
|
-
- [π― Production Ready](#-production-ready)
|
|
56
|
-
- [π Version Notes](#-version-notes)
|
|
57
|
-
- [π§ Standard Configuration](#-standard-configuration)
|
|
58
|
-
- [π Simple Example: Automatic Context Propagation](#-simple-example-automatic-context-propagation)
|
|
59
|
-
- [ποΈ Singleton Pattern - Intelligent Resource Management](#οΈ-singleton-pattern---intelligent-resource-management)
|
|
60
|
-
- [**π― Named Instance Management**](#-named-instance-management)
|
|
61
|
-
- [**π Loggers - On-Demand Creation with Singleton Management**](#-loggers---on-demand-creation-with-singleton-management)
|
|
62
|
-
- [**π Infrastructure Resources - Pre-configured Singletons**](#-infrastructure-resources---pre-configured-singletons)
|
|
63
|
-
- [**π Automatic Resource Lifecycle**](#-automatic-resource-lifecycle)
|
|
64
|
-
- [**π Logger Lifecycle (On-Demand)**](#-logger-lifecycle-on-demand)
|
|
65
|
-
- [**π Infrastructure Lifecycle (Pre-configured)**](#-infrastructure-lifecycle-pre-configured)
|
|
66
|
-
- [**β‘ Production Benefits**](#-production-benefits)
|
|
67
|
-
- [π§ͺ Testing Revolution](#-testing-revolution)
|
|
68
|
-
- [**π― Zero Boilerplate Testing with SyntropyLogMock**](#-zero-boilerplate-testing-with-syntropylogmock)
|
|
69
|
-
- [**π What's New in v0.7.0**](#-whats-new-in-v070)
|
|
70
|
-
- [**β
Benefits**](#-benefits)
|
|
71
|
-
- [π¦ Ecosystem](#-ecosystem)
|
|
72
|
-
- [π Examples](#-examples)
|
|
73
|
-
- [β
**Complete \& Tested (00-13, 20-24, 28-32)**](#-complete--tested-00-13-20-24-28-32)
|
|
74
|
-
- [π§ **In Development (14-19, 25-27)**](#-in-development-14-19-25-27)
|
|
46
|
+
- [π§ Configuration Guide](#-configuration-guide)
|
|
47
|
+
- [π§ͺ Testing Guide](#-testing-guide)
|
|
48
|
+
- [π¦ Examples & Ecosystem](#-examples--ecosystem)
|
|
49
|
+
- [π Security & Transparency](#-security--transparency)
|
|
75
50
|
- [π€ Contributing](#-contributing)
|
|
76
51
|
- [π License](#-license)
|
|
77
|
-
- [π Support](#-support)
|
|
78
|
-
|
|
79
52
|
|
|
80
53
|
---
|
|
81
54
|
|
|
82
|
-
##
|
|
55
|
+
## π― What is SyntropyLog?
|
|
56
|
+
|
|
57
|
+
**SyntropyLog is an instance manager with observability for Node.js applications.** It's not just a logger - it's a complete system that manages your application instances, their connections, and provides complete observability across your entire system with zero performance overhead.
|
|
83
58
|
|
|
84
|
-
|
|
59
|
+
### **π― Key Benefits:**
|
|
60
|
+
- **Zero Performance Impact** - Identical performance to Pino (industry standard)
|
|
61
|
+
- **Automatic Context Propagation** - Correlation IDs flow through all operations
|
|
62
|
+
- **Singleton Resource Management** - Prevents memory leaks and connection issues
|
|
63
|
+
- **Enterprise Security** - Built-in data masking and compliance features
|
|
64
|
+
- **Framework Agnostic** - Works with Express, Fastify, Koa, NestJS, and any Node.js app
|
|
85
65
|
|
|
66
|
+
### **π Enterprise Integration & APM:**
|
|
67
|
+
- **Currently, SyntropyLog does not include native APM**, but the architecture allows adding custom transports to integrate with enterprise tools
|
|
68
|
+
- **Ideal for teams** already using Jaeger, Zipkin, Elastic, or Prometheus who want to enrich their observability without vendor lock-in
|
|
69
|
+
- **Custom transport support** enables seamless integration with your existing monitoring stack
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## π Quick Start (30 seconds)
|
|
74
|
+
|
|
75
|
+
### **Step 1: Install**
|
|
86
76
|
```bash
|
|
87
77
|
npm install syntropylog
|
|
88
78
|
```
|
|
89
79
|
|
|
80
|
+
### **Step 2: Basic Setup**
|
|
90
81
|
```typescript
|
|
91
82
|
import { syntropyLog } from 'syntropylog';
|
|
92
83
|
|
|
@@ -102,410 +93,673 @@ await syntropyLog.init({
|
|
|
102
93
|
const logger = syntropyLog.getLogger();
|
|
103
94
|
logger.info('Hello, SyntropyLog!');
|
|
104
95
|
```
|
|
105
|
-
// Note: This shows the "zero boilerplate" usage pattern.
|
|
106
|
-
// Initialization and shutdown require the boilerplate shown in the documentation.
|
|
107
96
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
97
|
+
### **Step 3: Add Graceful Shutdown (REQUIRED)**
|
|
98
|
+
```typescript
|
|
99
|
+
// Add this to your main application file
|
|
100
|
+
process.on('SIGTERM', async () => {
|
|
101
|
+
console.log('π Shutting down gracefully...');
|
|
102
|
+
await syntropyLog.shutdown();
|
|
103
|
+
process.exit(0);
|
|
104
|
+
});
|
|
111
105
|
|
|
112
|
-
|
|
106
|
+
process.on('SIGINT', async () => {
|
|
107
|
+
console.log('π Shutting down gracefully...');
|
|
108
|
+
await syntropyLog.shutdown();
|
|
109
|
+
process.exit(0);
|
|
110
|
+
});
|
|
111
|
+
```
|
|
113
112
|
|
|
114
|
-
|
|
115
|
-
- **π Automatic Correlation** - Distributed tracing across services, HTTP calls, and message brokers
|
|
116
|
-
- **π― Framework Agnostic** - Works with Express, Fastify, Koa, NestJS, and any Node.js app
|
|
117
|
-
- **π‘οΈ Security First** - Built-in data masking and compliance-ready logging
|
|
118
|
-
- **β‘ High Performance** - 45,000+ ops/sec with less than 1ms latency
|
|
119
|
-
- **ποΈ Singleton Pattern** - Prevents pod crashes by managing resource instances efficiently
|
|
113
|
+
> β οΈ **CRITICAL**: You **MUST** include graceful shutdown in ALL applications. This ensures logs are flushed and resources are cleaned up when your application stops.
|
|
120
114
|
|
|
121
|
-
|
|
115
|
+
---
|
|
122
116
|
|
|
123
|
-
|
|
117
|
+
## π οΈ CLI Tools
|
|
124
118
|
|
|
125
|
-
|
|
119
|
+
**SyntropyLog CLI tools are now available as a separate package for better modularity and focused development.**
|
|
126
120
|
|
|
127
|
-
|
|
121
|
+
### **Install CLI Tools**
|
|
122
|
+
```bash
|
|
123
|
+
npm install -g @syntropysoft/praetorian
|
|
124
|
+
```
|
|
128
125
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
126
|
+
### **Available Commands**
|
|
127
|
+
- `praetorian doctor` - Diagnose your SyntropyLog configuration
|
|
128
|
+
- `praetorian init` - Initialize a new SyntropyLog project
|
|
129
|
+
- `praetorian audit` - Audit your logging configuration
|
|
130
|
+
- `praetorian validate` - Validate configuration files
|
|
134
131
|
|
|
135
|
-
###
|
|
132
|
+
### **Why Separate Package?**
|
|
133
|
+
- **Focused Development** - CLI tools evolve independently
|
|
134
|
+
- **Reduced Bundle Size** - Core library stays lightweight
|
|
135
|
+
- **Better Maintenance** - Dedicated team for CLI features
|
|
136
|
+
- **Faster Updates** - CLI updates don't require core library releases
|
|
136
137
|
|
|
137
|
-
|
|
138
|
+
> π¦ **Note**: The CLI was previously included in this package but has been moved to `@syntropysoft/praetorian` for better modularity.
|
|
138
139
|
|
|
139
|
-
|
|
140
|
+
---
|
|
140
141
|
|
|
141
|
-
|
|
142
|
+
## π’ Enterprise Implementation Guide
|
|
142
143
|
|
|
143
|
-
|
|
144
|
+
**SyntropyLog is designed for enterprise environments and can be easily integrated into your internal infrastructure.**
|
|
144
145
|
|
|
145
|
-
###
|
|
146
|
+
### **π― Why SyntropyLog for Enterprise?**
|
|
146
147
|
|
|
147
|
-
|
|
148
|
+
1. **π Security by Default**
|
|
149
|
+
- Built-in data masking for sensitive information
|
|
150
|
+
- Compliance-ready logging with retention rules
|
|
151
|
+
- No external telemetry or tracking
|
|
152
|
+
- 100% open source and auditable
|
|
148
153
|
|
|
149
|
-
|
|
150
|
-
-
|
|
151
|
-
-
|
|
152
|
-
-
|
|
154
|
+
2. **ποΈ Scalable Architecture**
|
|
155
|
+
- Singleton pattern prevents resource leaks
|
|
156
|
+
- Automatic connection pooling
|
|
157
|
+
- Kubernetes-ready with proper lifecycle management
|
|
158
|
+
- Horizontal scaling support
|
|
153
159
|
|
|
154
|
-
|
|
160
|
+
3. **β‘ Performance Excellence**
|
|
161
|
+
- Zero measurable performance overhead
|
|
162
|
+
- Minimal bundle size impact (only +203 bytes vs Pino)
|
|
163
|
+
- Optimized for high-throughput applications
|
|
155
164
|
|
|
156
|
-
###
|
|
165
|
+
### **π’ Internal Implementation Strategy**
|
|
157
166
|
|
|
158
|
-
|
|
167
|
+
#### **Phase 1: Pilot Project (2-4 weeks)**
|
|
168
|
+
```typescript
|
|
169
|
+
// Start with a single microservice
|
|
170
|
+
await syntropyLog.init({
|
|
171
|
+
logger: {
|
|
172
|
+
serviceName: 'user-service',
|
|
173
|
+
level: 'info',
|
|
174
|
+
},
|
|
175
|
+
context: {
|
|
176
|
+
correlationIdHeader: 'X-Correlation-ID',
|
|
177
|
+
},
|
|
178
|
+
redis: {
|
|
179
|
+
instances: [{
|
|
180
|
+
instanceName: 'cache',
|
|
181
|
+
url: process.env.REDIS_URL,
|
|
182
|
+
}]
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
```
|
|
159
186
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
187
|
+
#### **Phase 2: Service Mesh Integration (4-8 weeks)**
|
|
188
|
+
```typescript
|
|
189
|
+
// Standardize across multiple services
|
|
190
|
+
const standardConfig = {
|
|
191
|
+
logger: {
|
|
192
|
+
level: process.env.LOG_LEVEL || 'info',
|
|
193
|
+
serviceName: process.env.SERVICE_NAME,
|
|
194
|
+
},
|
|
195
|
+
context: {
|
|
196
|
+
correlationIdHeader: 'X-Correlation-ID',
|
|
197
|
+
traceIdHeader: 'X-Trace-ID',
|
|
198
|
+
},
|
|
199
|
+
masking: {
|
|
200
|
+
fields: ['password', 'token', 'secret'],
|
|
201
|
+
preserveLength: true,
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
```
|
|
165
205
|
|
|
166
|
-
|
|
206
|
+
#### **Phase 3: Enterprise Features (8-12 weeks)**
|
|
207
|
+
```typescript
|
|
208
|
+
// Full enterprise configuration
|
|
209
|
+
await syntropyLog.init({
|
|
210
|
+
...standardConfig,
|
|
211
|
+
redis: {
|
|
212
|
+
instances: [
|
|
213
|
+
{ instanceName: 'cache', url: process.env.CACHE_REDIS_URL },
|
|
214
|
+
{ instanceName: 'session', url: process.env.SESSION_REDIS_URL },
|
|
215
|
+
]
|
|
216
|
+
},
|
|
217
|
+
brokers: {
|
|
218
|
+
instances: [
|
|
219
|
+
{ instanceName: 'events', adapter: new KafkaAdapter(kafkaConfig) },
|
|
220
|
+
{ instanceName: 'notifications', adapter: new RabbitMQAdapter(rabbitConfig) },
|
|
221
|
+
]
|
|
222
|
+
},
|
|
223
|
+
http: {
|
|
224
|
+
instances: [
|
|
225
|
+
{ instanceName: 'api', adapter: new AxiosAdapter(axiosConfig) },
|
|
226
|
+
]
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
```
|
|
167
230
|
|
|
168
|
-
|
|
231
|
+
### **π§ Enterprise Configuration Patterns**
|
|
169
232
|
|
|
170
|
-
**
|
|
233
|
+
#### **Environment-Based Configuration**
|
|
234
|
+
```typescript
|
|
235
|
+
// config/syntropylog.ts
|
|
236
|
+
export const getSyntropyConfig = (env: string) => {
|
|
237
|
+
const baseConfig = {
|
|
238
|
+
logger: {
|
|
239
|
+
level: process.env.LOG_LEVEL || 'info',
|
|
240
|
+
serviceName: process.env.SERVICE_NAME,
|
|
241
|
+
},
|
|
242
|
+
context: {
|
|
243
|
+
correlationIdHeader: 'X-Correlation-ID',
|
|
244
|
+
}
|
|
245
|
+
};
|
|
171
246
|
|
|
172
|
-
|
|
247
|
+
switch (env) {
|
|
248
|
+
case 'development':
|
|
249
|
+
return {
|
|
250
|
+
...baseConfig,
|
|
251
|
+
redis: { instances: [{ instanceName: 'cache', url: 'redis://localhost:6379' }] }
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
case 'staging':
|
|
255
|
+
return {
|
|
256
|
+
...baseConfig,
|
|
257
|
+
redis: { instances: [{ instanceName: 'cache', url: process.env.STAGING_REDIS_URL }] },
|
|
258
|
+
masking: { fields: ['password', 'token'] }
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
case 'production':
|
|
262
|
+
return {
|
|
263
|
+
...baseConfig,
|
|
264
|
+
redis: { instances: [{ instanceName: 'cache', url: process.env.PROD_REDIS_URL }] },
|
|
265
|
+
masking: { fields: ['password', 'token', 'secret', 'apiKey'] },
|
|
266
|
+
loggingMatrix: {
|
|
267
|
+
default: ['correlationId', 'serviceName'],
|
|
268
|
+
error: ['*']
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
```
|
|
173
274
|
|
|
174
|
-
|
|
275
|
+
#### **Centralized Logging Infrastructure**
|
|
276
|
+
```typescript
|
|
277
|
+
// shared/syntropylog-setup.ts
|
|
278
|
+
export class SyntropyLogManager {
|
|
279
|
+
private static instance: SyntropyLogManager;
|
|
280
|
+
|
|
281
|
+
static getInstance(): SyntropyLogManager {
|
|
282
|
+
if (!SyntropyLogManager.instance) {
|
|
283
|
+
SyntropyLogManager.instance = new SyntropyLogManager();
|
|
284
|
+
}
|
|
285
|
+
return SyntropyLogManager.instance;
|
|
286
|
+
}
|
|
175
287
|
|
|
176
|
-
|
|
288
|
+
async initialize(serviceName: string) {
|
|
289
|
+
const config = getSyntropyConfig(process.env.NODE_ENV);
|
|
290
|
+
await syntropyLog.init({
|
|
291
|
+
...config,
|
|
292
|
+
logger: { ...config.logger, serviceName }
|
|
293
|
+
});
|
|
294
|
+
}
|
|
177
295
|
|
|
178
|
-
|
|
296
|
+
getLogger(context?: string) {
|
|
297
|
+
return syntropyLog.getLogger(context);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
getRedis(instanceName: string) {
|
|
301
|
+
return syntropyLog.getRedis(instanceName);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
```
|
|
179
305
|
|
|
180
|
-
###
|
|
306
|
+
### **π Enterprise Monitoring Integration**
|
|
181
307
|
|
|
308
|
+
#### **Prometheus Metrics**
|
|
182
309
|
```typescript
|
|
183
|
-
//
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
//
|
|
191
|
-
|
|
310
|
+
// Add custom metrics to your logs
|
|
311
|
+
const logger = syntropyLog.getLogger();
|
|
312
|
+
logger.info('API Request', {
|
|
313
|
+
endpoint: '/users',
|
|
314
|
+
method: 'GET',
|
|
315
|
+
duration: 150,
|
|
316
|
+
statusCode: 200,
|
|
317
|
+
// These will be automatically picked up by your monitoring system
|
|
318
|
+
metrics: {
|
|
319
|
+
request_duration_ms: 150,
|
|
320
|
+
requests_total: 1,
|
|
321
|
+
status_code: 200
|
|
322
|
+
}
|
|
323
|
+
});
|
|
192
324
|
```
|
|
193
325
|
|
|
194
|
-
|
|
326
|
+
#### **ELK Stack Integration**
|
|
327
|
+
```typescript
|
|
328
|
+
// Configure for ELK stack
|
|
329
|
+
await syntropyLog.init({
|
|
330
|
+
logger: {
|
|
331
|
+
serviceName: 'user-service',
|
|
332
|
+
level: 'info',
|
|
333
|
+
transports: [
|
|
334
|
+
new JsonConsoleTransport(), // Structured JSON for Logstash
|
|
335
|
+
]
|
|
336
|
+
},
|
|
337
|
+
context: {
|
|
338
|
+
correlationIdHeader: 'X-Correlation-ID',
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
```
|
|
195
342
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
343
|
+
### **π Enterprise Security Features**
|
|
344
|
+
|
|
345
|
+
#### **Data Masking**
|
|
346
|
+
```typescript
|
|
347
|
+
// Automatic sensitive data masking
|
|
348
|
+
await syntropyLog.init({
|
|
349
|
+
masking: {
|
|
350
|
+
fields: ['password', 'token', 'secret', 'apiKey', 'creditCard'],
|
|
351
|
+
preserveLength: true, // Shows **** instead of completely hiding
|
|
352
|
+
patterns: [
|
|
353
|
+
{ regex: /\\b\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}\\b/, replacement: '[CARD_NUMBER]' }
|
|
354
|
+
]
|
|
355
|
+
}
|
|
356
|
+
});
|
|
200
357
|
|
|
201
|
-
|
|
358
|
+
// Usage - sensitive data is automatically masked
|
|
359
|
+
logger.info('User login attempt', {
|
|
360
|
+
email: 'user@example.com',
|
|
361
|
+
password: 'secret123', // Will be masked as '********'
|
|
362
|
+
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' // Will be masked
|
|
363
|
+
});
|
|
364
|
+
```
|
|
202
365
|
|
|
366
|
+
#### **Compliance Logging**
|
|
203
367
|
```typescript
|
|
204
|
-
//
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
//
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
368
|
+
// GDPR/Compliance ready logging
|
|
369
|
+
await syntropyLog.init({
|
|
370
|
+
loggingMatrix: {
|
|
371
|
+
default: ['correlationId', 'serviceName', 'timestamp'],
|
|
372
|
+
audit: ['*'], // Log everything for audit trails
|
|
373
|
+
error: ['*', 'stackTrace', 'context'],
|
|
374
|
+
security: ['*', 'ipAddress', 'userAgent', 'requestId']
|
|
375
|
+
}
|
|
376
|
+
});
|
|
212
377
|
```
|
|
213
378
|
|
|
214
|
-
|
|
379
|
+
---
|
|
215
380
|
|
|
216
|
-
## π
|
|
381
|
+
## π Manual & Tutorials
|
|
217
382
|
|
|
218
|
-
|
|
219
|
-
- **[API Reference](https://syntropysoft.github.io/syntropylog-doc/docs/api-reference)** - Full API documentation *(in progress)*
|
|
220
|
-
- **[Examples](https://syntropysoft.github.io/syntropylog-doc/examples)** - 30 production-ready examples *(in progress)*
|
|
221
|
-
- **[Configuration Guide](https://syntropysoft.github.io/syntropylog-doc/docs/configuration)** - Advanced configuration *(in progress)*
|
|
383
|
+
### **π― Getting Started Tutorials**
|
|
222
384
|
|
|
223
|
-
|
|
385
|
+
#### **Tutorial 1: Basic Logging (5 minutes)**
|
|
386
|
+
```typescript
|
|
387
|
+
// 1. Install and initialize
|
|
388
|
+
import { syntropyLog } from 'syntropylog';
|
|
224
389
|
|
|
225
|
-
|
|
390
|
+
await syntropyLog.init({
|
|
391
|
+
logger: { serviceName: 'tutorial-app', level: 'info' }
|
|
392
|
+
});
|
|
226
393
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
- π **Stable Benchmarks** - Consistent results across multiple benchmark runs
|
|
233
|
-
- π§ͺ **Comprehensive Testing** - 769 tests passing with 100% MaskingEngine test coverage
|
|
394
|
+
// 2. Use basic logging
|
|
395
|
+
const logger = syntropyLog.getLogger();
|
|
396
|
+
logger.info('Application started');
|
|
397
|
+
logger.warn('This is a warning');
|
|
398
|
+
logger.error('This is an error', { error: 'Something went wrong' });
|
|
234
399
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
- π **Enhanced Testing** - Improved test coverage (88.93%) with comprehensive test helpers
|
|
239
|
-
- π§ͺ **Testing Framework** - SyntropyLogMock, BeaconRedisMock, and test helpers for zero-boilerplate testing
|
|
240
|
-
- π **32 Complete Examples** - Including testing patterns, message brokers, and enterprise patterns
|
|
241
|
-
- π― **Production Ready** - Kubernetes-ready with singleton pattern and resource management
|
|
242
|
-
- β‘ **Zero External Dependencies** - No Redis, brokers, or HTTP servers needed for testing
|
|
400
|
+
// 3. Add context
|
|
401
|
+
logger.info('User action', { userId: '123', action: 'login' });
|
|
402
|
+
```
|
|
243
403
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
404
|
+
#### **Tutorial 2: Context and Correlation (10 minutes)**
|
|
405
|
+
```typescript
|
|
406
|
+
// 1. Set up context management
|
|
407
|
+
await syntropyLog.init({
|
|
408
|
+
logger: { serviceName: 'context-demo', level: 'info' },
|
|
409
|
+
context: { correlationIdHeader: 'X-Correlation-ID' }
|
|
410
|
+
});
|
|
249
411
|
|
|
250
|
-
|
|
412
|
+
// 2. Create context for a request
|
|
413
|
+
const contextManager = syntropyLog.getContextManager();
|
|
414
|
+
contextManager.run(async () => {
|
|
415
|
+
// Set correlation ID
|
|
416
|
+
contextManager.set('X-Correlation-ID', 'req-123');
|
|
417
|
+
|
|
418
|
+
const logger = syntropyLog.getLogger();
|
|
419
|
+
logger.info('Request started'); // Automatically includes correlation ID
|
|
420
|
+
|
|
421
|
+
// All operations in this context will have the same correlation ID
|
|
422
|
+
await someAsyncOperation();
|
|
423
|
+
|
|
424
|
+
logger.info('Request completed');
|
|
425
|
+
});
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
#### **Tutorial 3: Redis Integration (15 minutes)**
|
|
429
|
+
```typescript
|
|
430
|
+
// 1. Configure Redis
|
|
431
|
+
await syntropyLog.init({
|
|
432
|
+
logger: { serviceName: 'redis-demo', level: 'info' },
|
|
433
|
+
context: { correlationIdHeader: 'X-Correlation-ID' },
|
|
434
|
+
redis: {
|
|
435
|
+
instances: [{
|
|
436
|
+
instanceName: 'cache',
|
|
437
|
+
url: 'redis://localhost:6379'
|
|
438
|
+
}]
|
|
439
|
+
}
|
|
440
|
+
});
|
|
251
441
|
|
|
252
|
-
|
|
442
|
+
// 2. Use Redis with automatic correlation
|
|
443
|
+
const redis = syntropyLog.getRedis('cache');
|
|
444
|
+
const logger = syntropyLog.getLogger();
|
|
253
445
|
|
|
446
|
+
// Set context
|
|
447
|
+
const contextManager = syntropyLog.getContextManager();
|
|
448
|
+
contextManager.run(async () => {
|
|
449
|
+
contextManager.set('X-Correlation-ID', 'user-456');
|
|
450
|
+
|
|
451
|
+
// All operations automatically include correlation ID
|
|
452
|
+
await redis.set('user:456:profile', JSON.stringify({ name: 'John' }));
|
|
453
|
+
const profile = await redis.get('user:456:profile');
|
|
454
|
+
|
|
455
|
+
logger.info('User profile cached', { userId: '456' });
|
|
456
|
+
});
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
### **π§ Advanced Configuration Tutorials**
|
|
460
|
+
|
|
461
|
+
#### **Tutorial 4: Custom Transports (20 minutes)**
|
|
254
462
|
```typescript
|
|
255
|
-
|
|
256
|
-
import {
|
|
257
|
-
|
|
463
|
+
// 1. Create custom transport
|
|
464
|
+
import { Transport } from 'syntropylog';
|
|
465
|
+
|
|
466
|
+
class SlackTransport extends Transport {
|
|
467
|
+
async log(level: string, message: string, meta: any) {
|
|
468
|
+
if (level === 'error') {
|
|
469
|
+
// Send errors to Slack
|
|
470
|
+
await this.sendToSlack({
|
|
471
|
+
text: `π¨ Error in ${meta.serviceName}: ${message}`,
|
|
472
|
+
attachments: [{ text: JSON.stringify(meta, null, 2) }]
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
258
477
|
|
|
478
|
+
// 2. Use custom transport
|
|
259
479
|
await syntropyLog.init({
|
|
260
480
|
logger: {
|
|
481
|
+
serviceName: 'slack-demo',
|
|
261
482
|
level: 'info',
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
483
|
+
transports: [
|
|
484
|
+
new PrettyConsoleTransport(),
|
|
485
|
+
new SlackTransport()
|
|
486
|
+
]
|
|
487
|
+
}
|
|
488
|
+
});
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
#### **Tutorial 5: HTTP Client Integration (25 minutes)**
|
|
492
|
+
```typescript
|
|
493
|
+
// 1. Configure HTTP client
|
|
494
|
+
import { AxiosAdapter } from '@syntropylog/adapters';
|
|
495
|
+
import axios from 'axios';
|
|
496
|
+
|
|
497
|
+
await syntropyLog.init({
|
|
498
|
+
logger: { serviceName: 'http-demo', level: 'info' },
|
|
499
|
+
context: { correlationIdHeader: 'X-Correlation-ID' },
|
|
269
500
|
http: {
|
|
270
|
-
instances: [
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
]
|
|
276
|
-
}
|
|
501
|
+
instances: [{
|
|
502
|
+
instanceName: 'api',
|
|
503
|
+
adapter: new AxiosAdapter(axios.create({
|
|
504
|
+
baseURL: 'https://api.example.com'
|
|
505
|
+
}))
|
|
506
|
+
}]
|
|
507
|
+
}
|
|
277
508
|
});
|
|
278
509
|
|
|
279
|
-
// Use
|
|
280
|
-
const apiClient = syntropyLog.getHttp('
|
|
510
|
+
// 2. Use instrumented HTTP client
|
|
511
|
+
const apiClient = syntropyLog.getHttp('api');
|
|
281
512
|
const logger = syntropyLog.getLogger();
|
|
282
513
|
|
|
283
|
-
//
|
|
284
|
-
await apiClient.request({
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
const paymentLogger = syntropyLog.getLogger('payment-service');
|
|
289
|
-
const cacheRedis = syntropyLog.getRedis('cache');
|
|
290
|
-
const sessionRedis = syntropyLog.getRedis('session');
|
|
291
|
-
const eventsBroker = syntropyLog.getBroker('events');
|
|
292
|
-
const notificationsBroker = syntropyLog.getBroker('notifications');
|
|
514
|
+
// All HTTP calls automatically include correlation ID and logging
|
|
515
|
+
const response = await apiClient.request({
|
|
516
|
+
method: 'GET',
|
|
517
|
+
url: '/users/123'
|
|
518
|
+
});
|
|
293
519
|
|
|
294
|
-
|
|
520
|
+
logger.info('API call completed', {
|
|
521
|
+
statusCode: response.status,
|
|
522
|
+
duration: response.duration
|
|
523
|
+
});
|
|
295
524
|
```
|
|
296
525
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
### **π― What You'll Learn**
|
|
302
|
-
- How to set up SyntropyLog in 30 seconds
|
|
303
|
-
- How context (correlation IDs) automatically propagates to all operations
|
|
304
|
-
- How to use it with Express.js and Fastify
|
|
305
|
-
- How Redis operations automatically include the same correlation ID
|
|
526
|
+
#### **Tutorial 6: Auditing & Custom Adapters (30 minutes)**
|
|
527
|
+
```typescript
|
|
528
|
+
// 1. Define a persistent adapter (e.g. for Postgres/Internal API)
|
|
529
|
+
import { ILogTransportAdapter, AdapterTransport, syntropyLog } from 'syntropylog';
|
|
306
530
|
|
|
307
|
-
|
|
531
|
+
class MyDatabaseAdapter implements ILogTransportAdapter {
|
|
532
|
+
async log(entry: any) {
|
|
533
|
+
// In a real app: await db.insert('audit_logs', entry);
|
|
534
|
+
console.log('Auditing to DB:', entry.message);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
308
537
|
|
|
309
|
-
|
|
310
|
-
// Just configure what you need
|
|
538
|
+
// 2. Configure with category routing and audit level
|
|
311
539
|
await syntropyLog.init({
|
|
312
|
-
logger: {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
}
|
|
540
|
+
logger: {
|
|
541
|
+
serviceName: 'secure-app',
|
|
542
|
+
level: 'info',
|
|
543
|
+
transports: {
|
|
544
|
+
default: [new ConsoleTransport()],
|
|
545
|
+
audit: [new AdapterTransport({ adapter: new MyDatabaseAdapter() })]
|
|
546
|
+
}
|
|
319
547
|
}
|
|
320
548
|
});
|
|
549
|
+
|
|
550
|
+
// 3. Usage: Audit logs bypass standard level filtering
|
|
551
|
+
const logger = syntropyLog.getLogger('audit');
|
|
552
|
+
await logger.audit('Sensitive User Action', { userId: '456' }); // Always persisted
|
|
321
553
|
```
|
|
322
554
|
|
|
323
|
-
###
|
|
555
|
+
### **π Universal Persistence (Storage Agnostic)**
|
|
556
|
+
Starting from v0.8.x, SyntropyLog includes a powerful way to persist logs to any destination without external dependencies. By using `UniversalAdapter` and `UniversalLogFormatter`, you can map your logs to any schema using JSON and provide an execution function.
|
|
324
557
|
|
|
325
|
-
#### **
|
|
558
|
+
#### **The Quickest Example: In-memory/Console Capture**
|
|
326
559
|
```typescript
|
|
327
|
-
|
|
328
|
-
|
|
560
|
+
const adapter = new UniversalAdapter({
|
|
561
|
+
executor: (data) => console.log('Captured by Adapter:', data)
|
|
562
|
+
});
|
|
329
563
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
contextManager.run(async () => {
|
|
335
|
-
// Get correlation ID from header OR generate one automatically
|
|
336
|
-
const correlationId = req.headers['x-correlation-id'] || contextManager.getCorrelationId();
|
|
337
|
-
contextManager.set('X-Correlation-ID', correlationId);
|
|
338
|
-
next();
|
|
339
|
-
});
|
|
340
|
-
};
|
|
341
|
-
}
|
|
564
|
+
const formatter = new UniversalLogFormatter({
|
|
565
|
+
mapping: { msg: 'message', severity: 'level' }
|
|
566
|
+
});
|
|
342
567
|
|
|
343
|
-
//
|
|
344
|
-
app.use(syntropyContextMiddleware());
|
|
568
|
+
// Result: { msg: "Hello", severity: "info" }
|
|
345
569
|
```
|
|
346
570
|
|
|
347
|
-
#### **
|
|
571
|
+
#### **Example: Persisting to MongoDB (Object-based)**
|
|
348
572
|
```typescript
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
573
|
+
import { UniversalAdapter, UniversalLogFormatter, syntropyLog } from 'syntropylog';
|
|
574
|
+
|
|
575
|
+
const mongoAdapter = new UniversalAdapter({
|
|
576
|
+
executor: (doc) => db.collection('logs').insertOne(doc)
|
|
577
|
+
});
|
|
352
578
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
579
|
+
const mongoFormatter = new UniversalLogFormatter({
|
|
580
|
+
mapping: {
|
|
581
|
+
user: 'metadata.userId',
|
|
582
|
+
event: 'message',
|
|
583
|
+
level: 'level',
|
|
584
|
+
payload: 'bindings' // Full object path
|
|
357
585
|
}
|
|
586
|
+
});
|
|
358
587
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
// Set context - this will be available to all operations
|
|
368
|
-
contextManager.set('X-Correlation-ID', correlationId);
|
|
369
|
-
contextManager.set('requestId', request.id);
|
|
370
|
-
contextManager.set('method', request.method);
|
|
371
|
-
contextManager.set('url', request.url);
|
|
372
|
-
});
|
|
588
|
+
await syntropyLog.init({
|
|
589
|
+
logger: {
|
|
590
|
+
transports: {
|
|
591
|
+
audit: [new AdapterTransport({
|
|
592
|
+
adapter: mongoAdapter,
|
|
593
|
+
formatter: mongoFormatter
|
|
594
|
+
})]
|
|
595
|
+
}
|
|
373
596
|
}
|
|
374
|
-
}
|
|
597
|
+
});
|
|
375
598
|
```
|
|
376
599
|
|
|
377
|
-
|
|
378
|
-
|
|
600
|
+
#### **Example: Generic SQL (Postgres/MySQL)**
|
|
379
601
|
```typescript
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
this.redis = syntropyLog.getRedis('cache');
|
|
384
|
-
this.logger = syntropyLog.getLogger();
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
async getProduct(id: string) {
|
|
388
|
-
// Try cache first
|
|
389
|
-
const cached = await this.redis.get(`product:${id}`);
|
|
390
|
-
if (cached) {
|
|
391
|
-
this.logger.info('Product found in cache', { id });
|
|
392
|
-
return JSON.parse(cached);
|
|
393
|
-
}
|
|
602
|
+
const sqlAdapter = new UniversalAdapter({
|
|
603
|
+
executor: ({ sql, values }) => pool.query(sql, values)
|
|
604
|
+
});
|
|
394
605
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
return product;
|
|
606
|
+
const sqlFormatter = new UniversalLogFormatter({
|
|
607
|
+
mapping: {
|
|
608
|
+
column_user: 'bindings.userId',
|
|
609
|
+
column_msg: 'message'
|
|
401
610
|
}
|
|
402
|
-
}
|
|
611
|
+
});
|
|
403
612
|
```
|
|
404
613
|
|
|
405
|
-
|
|
614
|
+
---
|
|
406
615
|
|
|
407
|
-
|
|
616
|
+
## β¨ Key Features
|
|
408
617
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
```
|
|
618
|
+
### **π Zero Boilerplate**
|
|
619
|
+
- Get started in 30 seconds with automatic context propagation
|
|
620
|
+
- No complex setup or configuration required
|
|
621
|
+
- Works out of the box with sensible defaults
|
|
414
622
|
|
|
415
|
-
###
|
|
623
|
+
### **π Automatic Correlation**
|
|
624
|
+
- Distributed tracing across services, HTTP calls, and message brokers
|
|
625
|
+
- Correlation IDs automatically propagate through all operations
|
|
626
|
+
- Complete request flow visibility without manual effort
|
|
416
627
|
|
|
417
|
-
|
|
418
|
-
-
|
|
419
|
-
-
|
|
420
|
-
-
|
|
421
|
-
- β
**Framework agnostic** - works with Express, Fastify, Koa, etc.
|
|
628
|
+
### **π― Framework Agnostic**
|
|
629
|
+
- Works with Express, Fastify, Koa, NestJS, and any Node.js app
|
|
630
|
+
- No framework-specific dependencies
|
|
631
|
+
- Easy integration with existing applications
|
|
422
632
|
|
|
423
|
-
###
|
|
633
|
+
### **π‘οΈ Security First**
|
|
634
|
+
- Built-in data masking for sensitive information
|
|
635
|
+
- Compliance-ready logging with retention rules
|
|
636
|
+
- No external telemetry or tracking
|
|
424
637
|
|
|
425
|
-
|
|
426
|
-
-
|
|
427
|
-
-
|
|
428
|
-
-
|
|
429
|
-
- Custom logging matrices
|
|
430
|
-
- And much more...
|
|
638
|
+
### **β‘ High Performance**
|
|
639
|
+
- 45,000+ ops/sec with less than 1ms latency
|
|
640
|
+
- Zero measurable performance overhead
|
|
641
|
+
- Minimal bundle size impact
|
|
431
642
|
|
|
432
|
-
**
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
643
|
+
### **ποΈ Singleton Pattern**
|
|
644
|
+
- Prevents pod crashes by managing resource instances efficiently
|
|
645
|
+
- Automatic connection pooling and resource management
|
|
646
|
+
- Kubernetes-ready with proper lifecycle management
|
|
436
647
|
|
|
437
|
-
|
|
648
|
+
---
|
|
438
649
|
|
|
439
|
-
|
|
650
|
+
## π Performance & Benchmarks
|
|
440
651
|
|
|
441
|
-
|
|
442
|
-
SyntropyLog uses different patterns for different resource types:
|
|
652
|
+
**SyntropyLog achieves a remarkable technical milestone: offering advanced distributed tracing and instance management capabilities with zero performance impact.**
|
|
443
653
|
|
|
444
|
-
|
|
445
|
-
Loggers are the **only resources created on-demand** and managed as singletons:
|
|
654
|
+
### **π Benchmark Results**
|
|
446
655
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
// Logger derivatives - Create specialized loggers from templates
|
|
454
|
-
const userErrorLogger = syntropyLog.getLogger('user-service:errors'); // New instance
|
|
455
|
-
const userDebugLogger = syntropyLog.getLogger('user-service:debug'); // New instance
|
|
456
|
-
|
|
457
|
-
// Memory efficient - Only creates what you request
|
|
458
|
-
// If you create 200 loggers, you get exactly 200 logger instances
|
|
459
|
-
// No more, no less - controlled resource allocation
|
|
460
|
-
```
|
|
656
|
+
| Logger | Bundle Size (JS) | Performance Time | vs No Logger | vs Pino |
|
|
657
|
+
|--------|------------------|------------------|--------------|---------|
|
|
658
|
+
| No Logger | 5 KB | 3 ms | - | - |
|
|
659
|
+
| Pino | 5 KB | 2 ms | -193 B | - |
|
|
660
|
+
| **SyntropyLog** | **5 KB** | **2 ms** | **+10 B** | **+203 B (1.03x) / +0 ms (1.00x)** |
|
|
461
661
|
|
|
462
|
-
|
|
463
|
-
|
|
662
|
+
### **π Key Achievements**
|
|
663
|
+
|
|
664
|
+
1. **Zero Performance Overhead** - Identical performance to Pino
|
|
665
|
+
2. **Minimal Bundle Size** - Only 203 bytes larger than Pino
|
|
666
|
+
3. **Advanced Features** - Distributed tracing, resource management, data masking
|
|
667
|
+
4. **Enterprise Ready** - Security and compliance features included
|
|
668
|
+
|
|
669
|
+
---
|
|
670
|
+
|
|
671
|
+
## π Core Philosophy: Silent Observer
|
|
672
|
+
|
|
673
|
+
**SyntropyLog follows the "Silent Observer" principle - we report what happened and nothing more.**
|
|
674
|
+
|
|
675
|
+
### **π« Never Interrupts Your Application**
|
|
464
676
|
|
|
465
677
|
```typescript
|
|
466
|
-
//
|
|
467
|
-
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
console.log(eventsBroker === eventsBroker); // true β
(pre-configured singleton)
|
|
476
|
-
console.log(apiClient === apiClient); // true β
(pre-configured singleton)
|
|
678
|
+
// β
Your application continues running, even if logging fails
|
|
679
|
+
try {
|
|
680
|
+
const result = await database.query('SELECT * FROM users');
|
|
681
|
+
logger.info('Query successful', { count: result.length });
|
|
682
|
+
} catch (error) {
|
|
683
|
+
// Your error handling continues normally
|
|
684
|
+
logger.error('Database error', { error: error.message });
|
|
685
|
+
// Application logic continues...
|
|
686
|
+
}
|
|
477
687
|
```
|
|
478
688
|
|
|
479
|
-
###
|
|
480
|
-
The framework manages resources differently based on their type:
|
|
689
|
+
### **π Error Handling Strategy**
|
|
481
690
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
- **Memory efficient**: If you create 200 loggers, you get exactly 200 instances
|
|
691
|
+
1. **Configuration Errors** β Application fails to start (as expected)
|
|
692
|
+
2. **Pipeline Errors** β Error reported to transports, application continues
|
|
693
|
+
3. **Serializer Errors** β Error reported to transports, application continues
|
|
694
|
+
4. **Transport Errors** β Error reported to console, application continues
|
|
487
695
|
|
|
488
|
-
|
|
489
|
-
- **During init()**: Creates Redis, broker, and HTTP instances based on configuration
|
|
490
|
-
- **Runtime calls**: Returns pre-configured instances (no new creation)
|
|
491
|
-
- **Connection pooling**: Reuses existing connections efficiently
|
|
492
|
-
- **Consistent state**: Same instances across your entire application
|
|
696
|
+
**Think of SyntropyLog as a journalist - we observe, report, and never interfere with the main story.**
|
|
493
697
|
|
|
494
|
-
|
|
495
|
-
This pattern provides critical advantages in production environments:
|
|
698
|
+
---
|
|
496
699
|
|
|
497
|
-
|
|
498
|
-
- **π Connection Efficiency**: Reuses existing connections instead of creating new ones
|
|
499
|
-
- **π Consistent Observability**: Same logger instance ensures consistent correlation IDs
|
|
500
|
-
- **β‘ Performance**: Eliminates overhead of creating duplicate resources
|
|
501
|
-
- **ποΈ Resource Management**: Automatic cleanup and connection pooling
|
|
502
|
-
- **π Kubernetes Ready**: Essential for containerized environments where memory is limited
|
|
700
|
+
## π§ Configuration Guide
|
|
503
701
|
|
|
504
|
-
|
|
702
|
+
### **Basic Configuration**
|
|
703
|
+
```typescript
|
|
704
|
+
await syntropyLog.init({
|
|
705
|
+
logger: {
|
|
706
|
+
serviceName: 'my-app',
|
|
707
|
+
level: 'info', // debug, info, warn, error, audit
|
|
708
|
+
},
|
|
709
|
+
context: {
|
|
710
|
+
correlationIdHeader: 'X-Correlation-ID',
|
|
711
|
+
}
|
|
712
|
+
});
|
|
713
|
+
```
|
|
505
714
|
|
|
506
|
-
###
|
|
715
|
+
### **Advanced Configuration**
|
|
716
|
+
```typescript
|
|
717
|
+
await syntropyLog.init({
|
|
718
|
+
logger: {
|
|
719
|
+
serviceName: 'my-app',
|
|
720
|
+
level: 'info',
|
|
721
|
+
transports: {
|
|
722
|
+
default: [new PrettyConsoleTransport()],
|
|
723
|
+
audit: [new MySecureTransport()]
|
|
724
|
+
}
|
|
725
|
+
},
|
|
726
|
+
context: {
|
|
727
|
+
correlationIdHeader: 'X-Correlation-ID',
|
|
728
|
+
traceIdHeader: 'X-Trace-ID',
|
|
729
|
+
},
|
|
730
|
+
redis: {
|
|
731
|
+
instances: [
|
|
732
|
+
{ instanceName: 'cache', url: 'redis://localhost:6379' },
|
|
733
|
+
{ instanceName: 'session', url: 'redis://localhost:6380' },
|
|
734
|
+
]
|
|
735
|
+
},
|
|
736
|
+
brokers: {
|
|
737
|
+
instances: [
|
|
738
|
+
{ instanceName: 'events', adapter: new KafkaAdapter(kafkaConfig) },
|
|
739
|
+
]
|
|
740
|
+
},
|
|
741
|
+
http: {
|
|
742
|
+
instances: [
|
|
743
|
+
{ instanceName: 'api', adapter: new AxiosAdapter(axiosConfig) },
|
|
744
|
+
]
|
|
745
|
+
},
|
|
746
|
+
masking: {
|
|
747
|
+
fields: ['password', 'token', 'secret'],
|
|
748
|
+
preserveLength: true,
|
|
749
|
+
},
|
|
750
|
+
loggingMatrix: {
|
|
751
|
+
default: ['correlationId', 'serviceName'],
|
|
752
|
+
error: ['*'],
|
|
753
|
+
audit: ['*'],
|
|
754
|
+
}
|
|
755
|
+
});
|
|
756
|
+
```
|
|
507
757
|
|
|
508
|
-
|
|
758
|
+
---
|
|
759
|
+
|
|
760
|
+
## π§ͺ Testing Guide
|
|
761
|
+
|
|
762
|
+
### **Zero Boilerplate Testing**
|
|
509
763
|
|
|
510
764
|
```typescript
|
|
511
765
|
import { describe, it, expect, beforeEach } from 'vitest';
|
|
@@ -524,47 +778,51 @@ describe('UserService', () => {
|
|
|
524
778
|
});
|
|
525
779
|
|
|
526
780
|
it('should create user successfully', async () => {
|
|
527
|
-
const result = await userService.createUser({
|
|
781
|
+
const result = await userService.createUser({
|
|
782
|
+
name: 'John',
|
|
783
|
+
email: 'john@example.com'
|
|
784
|
+
});
|
|
528
785
|
expect(result).toHaveProperty('userId');
|
|
529
786
|
expect(result.name).toBe('John');
|
|
530
787
|
});
|
|
531
788
|
});
|
|
532
789
|
```
|
|
533
790
|
|
|
534
|
-
###
|
|
535
|
-
|
|
536
|
-
- **π Enterprise Security** - GitHub Dependabot, CodeQL static analysis, and automated vulnerability scanning
|
|
537
|
-
- **π‘οΈ Branch Protection** - Complete CI/CD pipeline with status checks and quality gates
|
|
538
|
-
- **π Enhanced Testing** - Improved test coverage (88.93%) with comprehensive test helpers
|
|
539
|
-
- **π§ͺ Testing Framework** - SyntropyLogMock, BeaconRedisMock, and test helpers for zero-boilerplate testing
|
|
540
|
-
- **π 32 Complete Examples** - Including testing patterns, message brokers, and enterprise patterns
|
|
541
|
-
- **π― Production Ready** - Kubernetes-ready with singleton pattern and resource management
|
|
542
|
-
- **β‘ Zero External Dependencies** - No Redis, brokers, or HTTP servers needed for testing
|
|
543
|
-
|
|
544
|
-
### **β
Benefits**
|
|
545
|
-
|
|
791
|
+
### **Benefits**
|
|
546
792
|
- **π« No Connection Boilerplate** - No init/shutdown in tests
|
|
547
793
|
- **β‘ Lightning Fast** - Everything runs in memory
|
|
548
794
|
- **π Reliable** - No network issues or state conflicts
|
|
549
795
|
- **π― Focused** - Test business logic, not framework internals
|
|
550
|
-
- **π Framework Agnostic** - Works with Vitest, Jest, and any test runner
|
|
551
|
-
|
|
552
|
-
[View Testing Examples β](https://syntropysoft.github.io/syntropylog-doc/docs/examples/28-testing-patterns-vitest)
|
|
553
|
-
|
|
554
|
-
## π¦ Ecosystem
|
|
555
|
-
|
|
556
|
-
- **[syntropylog](https://www.npmjs.com/package/syntropylog)** - Core framework
|
|
557
|
-
- **[@syntropylog/adapters](https://www.npmjs.com/package/@syntropylog/adapters)** - HTTP and broker adapters
|
|
558
|
-
- **[@syntropylog/types](https://www.npmjs.com/package/@syntropylog/types)** - TypeScript types
|
|
559
|
-
- **[syntropylog-examples](https://github.com/Syntropysoft/syntropylog-examples)** - 32 complete examples
|
|
560
|
-
|
|
561
|
-
## π Examples
|
|
562
|
-
|
|
563
|
-
Complete examples demonstrating SyntropyLog features:
|
|
564
796
|
|
|
565
|
-
|
|
797
|
+
---
|
|
566
798
|
|
|
567
|
-
|
|
799
|
+
## π¦ Examples & Ecosystem
|
|
800
|
+
|
|
801
|
+
### **π₯ Ejemplos que "Revientan por los Aires"**
|
|
802
|
+
|
|
803
|
+
Estos ejemplos demuestran el poder real de SyntropyLog en aplicaciones complejas del mundo real:
|
|
804
|
+
|
|
805
|
+
#### **π [Microservicio Completo](./examples/01-microservice-complete/)**
|
|
806
|
+
**E-commerce API con observabilidad total**
|
|
807
|
+
- β
**Distributed tracing** automΓ‘tico entre servicios
|
|
808
|
+
- β
**Cache inteligente** con Redis y correlation IDs
|
|
809
|
+
- β
**HTTP clients instrumentados** para APIs externas
|
|
810
|
+
- β
**Data masking automΓ‘tico** para datos sensibles
|
|
811
|
+
- β
**Event streaming** con message brokers
|
|
812
|
+
- β
**Performance tracking** en todas las operaciones
|
|
813
|
+
- β
**Error handling robusto** con context preservation
|
|
814
|
+
|
|
815
|
+
#### **π₯ [Eventos en Tiempo Real](./examples/02-realtime-events/)**
|
|
816
|
+
**WebSocket server con analytics en tiempo real**
|
|
817
|
+
- β
**WebSocket management** con observabilidad automΓ‘tica
|
|
818
|
+
- β
**Real-time analytics** y mΓ©tricas de performance
|
|
819
|
+
- β
**Connection pooling** y room management
|
|
820
|
+
- β
**Event processing pipeline** con Redis persistence
|
|
821
|
+
- β
**Load balancing** y automatic error recovery
|
|
822
|
+
- β
**Security** con rate limiting y data masking
|
|
823
|
+
- β
**Production-ready** con Kubernetes deployment
|
|
824
|
+
|
|
825
|
+
### **π― Ejemplos BΓ‘sicos (00-09)**
|
|
568
826
|
- **00**: Basic Setup - Simple initialization and logging
|
|
569
827
|
- **01**: Configuration - Environment-based configuration
|
|
570
828
|
- **02**: Context Management - Correlation IDs and request tracking
|
|
@@ -578,11 +836,11 @@ Complete examples demonstrating SyntropyLog features:
|
|
|
578
836
|
|
|
579
837
|
#### **π HTTP Framework Integration (10-15)**
|
|
580
838
|
- **10**: Express.js - Traditional Express server with context
|
|
581
|
-
- **11**:
|
|
582
|
-
- **12**: Express + Redis + Axios - Complete microservice with caching
|
|
583
|
-
- **13**: Fastify + Redis - High-performance Fastify with automatic context
|
|
839
|
+
- **11**: Custom HTTP Adapter - Creating custom adapters
|
|
840
|
+
- **12**: Express + Redis + Axios - Complete microservice with caching
|
|
841
|
+
- **13**: Fastify + Redis - High-performance Fastify with automatic context
|
|
584
842
|
- **14**: NestJS Integration - Enterprise-grade framework with decorators
|
|
585
|
-
- **15**:
|
|
843
|
+
- **15**: Koa + Redis - Modern Koa server with Redis caching
|
|
586
844
|
|
|
587
845
|
#### **π‘ Message Brokers (20-24)**
|
|
588
846
|
- **20**: Kafka Integration - Event streaming with correlation
|
|
@@ -598,43 +856,117 @@ Complete examples demonstrating SyntropyLog features:
|
|
|
598
856
|
- **31**: Serializer Testing - Custom serializer validation
|
|
599
857
|
- **32**: Transport Spies - Testing log outputs and formats
|
|
600
858
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
859
|
+
Estos ejemplos demuestran el poder real de SyntropyLog en aplicaciones complejas del mundo real:
|
|
860
|
+
|
|
861
|
+
#### **π [Microservicio Completo](./examples/01-microservice-complete/)**
|
|
862
|
+
**E-commerce API con observabilidad total**
|
|
863
|
+
- β
**Distributed tracing** automΓ‘tico entre servicios
|
|
864
|
+
- β
**Cache inteligente** con Redis y correlation IDs
|
|
865
|
+
- β
**HTTP clients instrumentados** para APIs externas
|
|
866
|
+
- β
**Data masking automΓ‘tico** para datos sensibles
|
|
867
|
+
- β
**Event streaming** con message brokers
|
|
868
|
+
- β
**Performance tracking** en todas las operaciones
|
|
869
|
+
- β
**Error handling robusto** con context preservation
|
|
870
|
+
|
|
871
|
+
#### **π₯ [Eventos en Tiempo Real](./examples/02-realtime-events/)**
|
|
872
|
+
**WebSocket server con analytics en tiempo real**
|
|
873
|
+
- β
**WebSocket management** con observabilidad automΓ‘tica
|
|
874
|
+
- β
**Real-time analytics** y mΓ©tricas de performance
|
|
875
|
+
- β
**Connection pooling** y room management
|
|
876
|
+
- β
**Event processing pipeline** con Redis persistence
|
|
877
|
+
- β
**Load balancing** y automatic error recovery
|
|
878
|
+
- β
**Security** con rate limiting y data masking
|
|
879
|
+
- β
**Production-ready** con Kubernetes deployment
|
|
880
|
+
|
|
881
|
+
### **π¦ Ecosystem**
|
|
882
|
+
|
|
883
|
+
- **[syntropylog](https://www.npmjs.com/package/syntropylog)** - Core framework
|
|
884
|
+
- **[@syntropylog/adapters](https://www.npmjs.com/package/@syntropylog/adapters)** - HTTP and broker adapters
|
|
885
|
+
- **[@syntropylog/types](https://www.npmjs.com/package/@syntropylog/types)** - TypeScript types
|
|
886
|
+
- **[syntropylog-examples](https://github.com/Syntropysoft/syntropylog-examples)** - 32 complete examples
|
|
604
887
|
|
|
605
|
-
|
|
888
|
+
---
|
|
606
889
|
|
|
607
|
-
|
|
608
|
-
1. **Example 00** - Basic setup and logging
|
|
609
|
-
2. **Example 02** - Understanding context and correlation IDs
|
|
610
|
-
3. **Example 12** - Real-world Express + Redis integration
|
|
611
|
-
4. **Example 13** - High-performance Fastify with automatic context
|
|
890
|
+
## π Security & Transparency
|
|
612
891
|
|
|
613
|
-
**
|
|
614
|
-
- **Express.js**: Examples 10, 12
|
|
615
|
-
- **Fastify**: Example 13 (recommended for performance)
|
|
616
|
-
- **Koa.js**: Example 11
|
|
892
|
+
**We invite any member of the community to audit the code. If you find anything suspicious, please open an issue or a pull request.**
|
|
617
893
|
|
|
618
|
-
**
|
|
619
|
-
-
|
|
620
|
-
-
|
|
894
|
+
### **π Security Features**
|
|
895
|
+
- 100% open source and public
|
|
896
|
+
- No hidden telemetry, tracking, or obfuscated code
|
|
897
|
+
- Automated dependency and vulnerability scans via GitHub Dependabot and CodeQL
|
|
898
|
+
- High code coverage and comprehensive testing
|
|
899
|
+
- External and community audits are welcome
|
|
621
900
|
|
|
622
|
-
|
|
901
|
+
### **π’ Enterprise Security**
|
|
902
|
+
- Built-in data masking for sensitive information
|
|
903
|
+
- Compliance-ready logging with retention rules
|
|
904
|
+
- GDPR and SOC2 compliance features
|
|
905
|
+
- No external data transmission
|
|
906
|
+
|
|
907
|
+
---
|
|
623
908
|
|
|
624
909
|
## π€ Contributing
|
|
625
910
|
|
|
626
911
|
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
627
912
|
|
|
913
|
+
### **π― How to Contribute**
|
|
914
|
+
1. Fork the repository
|
|
915
|
+
2. Create a feature branch
|
|
916
|
+
3. Make your changes
|
|
917
|
+
4. Add tests for new functionality
|
|
918
|
+
5. Submit a pull request
|
|
919
|
+
|
|
920
|
+
### **π§ Development Setup**
|
|
921
|
+
```bash
|
|
922
|
+
git clone https://github.com/Syntropysoft/SyntropyLog.git
|
|
923
|
+
cd SyntropyLog
|
|
924
|
+
npm install
|
|
925
|
+
npm run test
|
|
926
|
+
```
|
|
927
|
+
|
|
928
|
+
---
|
|
929
|
+
|
|
628
930
|
## π License
|
|
629
931
|
|
|
630
932
|
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
|
|
631
933
|
|
|
632
|
-
|
|
934
|
+
---
|
|
633
935
|
|
|
634
|
-
-
|
|
635
|
-
- π [Issues](https://github.com/Syntropysoft/SyntropyLog/issues)
|
|
636
|
-
- π¬ [Discussions](https://github.com/Syntropysoft/SyntropyLog/discussions)
|
|
936
|
+
**From Chaos to Clarity** - Ship resilient, secure, and cost-effective Node.js applications with confidence.
|
|
637
937
|
|
|
638
938
|
---
|
|
639
939
|
|
|
640
|
-
|
|
940
|
+
## π¨βπ» Author & Contact
|
|
941
|
+
|
|
942
|
+
<p align="center">
|
|
943
|
+
<strong>Built with β€οΈ by the SyntropySoft Team</strong>
|
|
944
|
+
</p>
|
|
945
|
+
|
|
946
|
+
### **π€ Get in Touch**
|
|
947
|
+
- **π¨βπΌ Gabriel Alejandro Gomez** - Lead Developer & Architect
|
|
948
|
+
- **πΌ [LinkedIn](https://www.linkedin.com/in/gabriel-alejandro-gomez-652a5111/)** - Connect for enterprise partnerships
|
|
949
|
+
- **π§ [Email](mailto:gabriel70@gmail.com)** - Technical questions & support
|
|
950
|
+
- **π’ [SyntropySoft](https://syntropysoft.com)** - Enterprise solutions & consulting
|
|
951
|
+
|
|
952
|
+
### **πΌ Enterprise Partnerships**
|
|
953
|
+
We specialize in enterprise observability solutions and custom integrations. Whether you need:
|
|
954
|
+
- **Custom transport development** for your existing APM stack
|
|
955
|
+
- **Enterprise deployment** and configuration
|
|
956
|
+
- **Performance optimization** and scaling strategies
|
|
957
|
+
- **Compliance implementation** (GDPR, SOC2, HIPAA)
|
|
958
|
+
|
|
959
|
+
**Let's discuss how SyntropyLog can enhance your observability strategy.**
|
|
960
|
+
|
|
961
|
+
---
|
|
962
|
+
|
|
963
|
+
<p align="center">
|
|
964
|
+
<em>Empowering high-performance teams with enterprise-grade observability</em>
|
|
965
|
+
</p>
|
|
966
|
+
|
|
967
|
+
---
|
|
968
|
+
|
|
969
|
+
<p align="center">
|
|
970
|
+
<strong>Thank you for considering SyntropyLog for your mission-critical systems.</strong><br>
|
|
971
|
+
<em>β Gabriel</em>
|
|
972
|
+
</p>
|