@onlineapps/service-wrapper 2.1.5 → 2.1.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlineapps/service-wrapper",
3
- "version": "2.1.5",
3
+ "version": "2.1.7",
4
4
  "description": "Thin orchestration layer for microservices - delegates all infrastructure concerns to specialized connectors",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -22,7 +22,6 @@ const CookbookConnector = require('@onlineapps/conn-orch-cookbook');
22
22
  const CacheConnector = require('@onlineapps/conn-base-cache');
23
23
  const ErrorHandlerConnector = require('@onlineapps/conn-infra-error-handler');
24
24
  const { ValidationOrchestrator } = require('@onlineapps/conn-orch-validator');
25
- const { createHttpLogging } = require('./HttpLoggingMiddleware');
26
25
 
27
26
  const INFRA_QUEUE_OWNERS = {
28
27
  'workflow.init': 'Gateway (api_gateway)',
@@ -559,17 +558,9 @@ class ServiceWrapper {
559
558
  // Logger is now available, use it
560
559
  this.logger.info('Monitoring connector initialized', { logsDir });
561
560
 
562
- // Apply HTTP logging middleware (configurable via wrapper.logging)
563
- if (this.app) {
564
- const loggingConfig = this.config.wrapper?.logging || {};
565
- const httpLogging = createHttpLogging(() => this.logger, loggingConfig);
566
-
567
- // Store for access from outside if needed
568
- this.httpLogging = httpLogging;
569
-
570
- // Apply middlewares to Express app
571
- httpLogging.applyTo(this.app);
572
- }
561
+ // NOTE: HTTP logging middleware is applied directly in service's app.js
562
+ // using middlewares/httpLogging.js with lazy logger access via lib/logger.js
563
+ // Configuration is in conn-config/config.json -> wrapper.logging (for reference)
573
564
  }
574
565
 
575
566
  /**
package/src/index.js CHANGED
@@ -13,15 +13,16 @@
13
13
 
14
14
  const ServiceWrapper = require('./ServiceWrapper');
15
15
  const { ConfigLoader } = require('./ConfigLoader');
16
- const HttpLoggingMiddleware = require('./HttpLoggingMiddleware');
17
16
 
18
17
  // Note: WorkflowProcessor and ApiCaller functionality has been moved to connectors:
19
18
  // - WorkflowProcessor -> @onlineapps/conn-orch-orchestrator
20
19
  // - ApiCaller -> @onlineapps/conn-orch-api-mapper
21
20
 
21
+ // Note: HTTP logging middleware is now in each service's middlewares/httpLogging.js
22
+ // It uses lazy logger access via lib/logger.js (set after wrapper.initialize())
23
+
22
24
  module.exports = ServiceWrapper;
23
25
  module.exports.ServiceWrapper = ServiceWrapper;
24
26
  module.exports.ConfigLoader = ConfigLoader;
25
- module.exports.HttpLoggingMiddleware = HttpLoggingMiddleware;
26
27
  module.exports.default = ServiceWrapper;
27
- module.exports.VERSION = '2.1.4';
28
+ module.exports.VERSION = '2.1.6';
@@ -1,295 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * HTTP Logging Middleware
5
- *
6
- * Configurable request/response logging for business services.
7
- * Logs to both local files and central monitoring via wrapper.logger.
8
- *
9
- * Configuration in conn-config/config.json:
10
- * {
11
- * "wrapper": {
12
- * "logging": {
13
- * "enabled": true, // Master switch
14
- * "level": "info", // Log level: debug, info, warn, error
15
- * "requests": {
16
- * "enabled": true, // Log incoming requests
17
- * "bodies": true, // Include request bodies
18
- * "headers": false // Include request headers (careful with auth tokens)
19
- * },
20
- * "responses": {
21
- * "enabled": true, // Log outgoing responses
22
- * "bodies": true // Include response bodies
23
- * },
24
- * "excludePaths": [ // Paths to exclude from logging
25
- * "/health",
26
- * "/status",
27
- * "/metrics"
28
- * ]
29
- * }
30
- * }
31
- * }
32
- */
33
-
34
- const DEFAULT_CONFIG = {
35
- enabled: true,
36
- level: 'info',
37
- requests: {
38
- enabled: true,
39
- bodies: true,
40
- headers: false
41
- },
42
- responses: {
43
- enabled: true,
44
- bodies: true
45
- },
46
- excludePaths: ['/health', '/status', '/metrics', '/specification']
47
- };
48
-
49
- /**
50
- * Merge user config with defaults
51
- */
52
- function mergeConfig(userConfig = {}) {
53
- return {
54
- enabled: userConfig.enabled ?? DEFAULT_CONFIG.enabled,
55
- level: userConfig.level ?? DEFAULT_CONFIG.level,
56
- requests: {
57
- enabled: userConfig.requests?.enabled ?? DEFAULT_CONFIG.requests.enabled,
58
- bodies: userConfig.requests?.bodies ?? DEFAULT_CONFIG.requests.bodies,
59
- headers: userConfig.requests?.headers ?? DEFAULT_CONFIG.requests.headers
60
- },
61
- responses: {
62
- enabled: userConfig.responses?.enabled ?? DEFAULT_CONFIG.responses.enabled,
63
- bodies: userConfig.responses?.bodies ?? DEFAULT_CONFIG.responses.bodies
64
- },
65
- excludePaths: userConfig.excludePaths ?? DEFAULT_CONFIG.excludePaths
66
- };
67
- }
68
-
69
- /**
70
- * Check if path should be excluded from logging
71
- */
72
- function shouldExclude(path, excludePaths) {
73
- return excludePaths.some(excluded => {
74
- // Exact match or prefix match
75
- return path === excluded || path.startsWith(excluded + '/');
76
- });
77
- }
78
-
79
- /**
80
- * Safely stringify body for logging
81
- */
82
- function safeStringify(body) {
83
- if (body === undefined || body === null) {
84
- return null;
85
- }
86
-
87
- if (typeof body === 'string') {
88
- // Already a string - could be JSON or plain text
89
- try {
90
- // Try to parse and re-stringify for consistent format
91
- return JSON.parse(body);
92
- } catch {
93
- return body;
94
- }
95
- }
96
-
97
- if (Buffer.isBuffer(body)) {
98
- return `[Buffer: ${body.length} bytes]`;
99
- }
100
-
101
- // Object - return as is (will be serialized by logger)
102
- return body;
103
- }
104
-
105
- /**
106
- * Create request logging middleware
107
- * @param {Function} getLogger - Function that returns logger instance
108
- * @param {Object} config - Logging configuration
109
- * @returns {Function} Express middleware
110
- */
111
- function createRequestLogger(getLogger, config) {
112
- const cfg = mergeConfig(config);
113
-
114
- return (req, res, next) => {
115
- // Skip if disabled
116
- if (!cfg.enabled || !cfg.requests.enabled) {
117
- return next();
118
- }
119
-
120
- // Skip excluded paths
121
- if (shouldExclude(req.path, cfg.excludePaths)) {
122
- return next();
123
- }
124
-
125
- const logger = getLogger();
126
- if (!logger) {
127
- return next();
128
- }
129
-
130
- // Build log data
131
- const logData = {
132
- type: 'request',
133
- method: req.method,
134
- path: req.path,
135
- url: req.originalUrl,
136
- ip: req.ip || req.connection?.remoteAddress,
137
- userAgent: req.get('user-agent')
138
- };
139
-
140
- // Add query params if present
141
- if (req.query && Object.keys(req.query).length > 0) {
142
- logData.query = req.query;
143
- }
144
-
145
- // Add request body if enabled
146
- if (cfg.requests.bodies && req.body && Object.keys(req.body).length > 0) {
147
- logData.body = safeStringify(req.body);
148
- }
149
-
150
- // Add headers if enabled
151
- if (cfg.requests.headers) {
152
- // Filter out sensitive headers
153
- const headers = { ...req.headers };
154
- delete headers.authorization;
155
- delete headers.cookie;
156
- logData.headers = headers;
157
- }
158
-
159
- // Store start time for response duration
160
- req._loggingStartTime = Date.now();
161
-
162
- logger.info('HTTP Request', logData);
163
- next();
164
- };
165
- }
166
-
167
- /**
168
- * Create response logging middleware
169
- * @param {Function} getLogger - Function that returns logger instance
170
- * @param {Object} config - Logging configuration
171
- * @returns {Function} Express middleware
172
- */
173
- function createResponseLogger(getLogger, config) {
174
- const cfg = mergeConfig(config);
175
-
176
- return (req, res, next) => {
177
- // Skip if disabled
178
- if (!cfg.enabled || !cfg.responses.enabled) {
179
- return next();
180
- }
181
-
182
- // Skip excluded paths
183
- if (shouldExclude(req.path, cfg.excludePaths)) {
184
- return next();
185
- }
186
-
187
- const logger = getLogger();
188
- if (!logger) {
189
- return next();
190
- }
191
-
192
- // Store original methods
193
- const originalSend = res.send;
194
- const originalJson = res.json;
195
-
196
- // Flag to prevent double logging
197
- let logged = false;
198
-
199
- const logResponse = (body) => {
200
- if (logged) return;
201
- logged = true;
202
-
203
- const duration = req._loggingStartTime
204
- ? Date.now() - req._loggingStartTime
205
- : null;
206
-
207
- const logData = {
208
- type: 'response',
209
- method: req.method,
210
- path: req.path,
211
- statusCode: res.statusCode,
212
- statusMessage: res.statusMessage
213
- };
214
-
215
- if (duration !== null) {
216
- logData.durationMs = duration;
217
- }
218
-
219
- // Add response body if enabled
220
- if (cfg.responses.bodies && body !== undefined) {
221
- logData.body = safeStringify(body);
222
- }
223
-
224
- // Choose log level based on status code
225
- if (res.statusCode >= 500) {
226
- logger.error('HTTP Response', logData);
227
- } else if (res.statusCode >= 400) {
228
- logger.warn('HTTP Response', logData);
229
- } else {
230
- logger.info('HTTP Response', logData);
231
- }
232
- };
233
-
234
- // Override res.send
235
- res.send = function(body) {
236
- logResponse(body);
237
- return originalSend.call(this, body);
238
- };
239
-
240
- // Override res.json
241
- res.json = function(body) {
242
- logResponse(body);
243
- return originalJson.call(this, body);
244
- };
245
-
246
- next();
247
- };
248
- }
249
-
250
- /**
251
- * Create combined HTTP logging middleware
252
- * @param {Function} getLogger - Function that returns logger instance
253
- * @param {Object} config - Logging configuration from wrapper.logging
254
- * @returns {Object} Object with requestLogger and responseLogger middlewares
255
- */
256
- function createHttpLogging(getLogger, config = {}) {
257
- const cfg = mergeConfig(config);
258
-
259
- return {
260
- config: cfg,
261
- requestLogger: createRequestLogger(getLogger, config),
262
- responseLogger: createResponseLogger(getLogger, config),
263
-
264
- /**
265
- * Apply both middlewares to Express app
266
- * @param {Object} app - Express application
267
- */
268
- applyTo(app) {
269
- if (!cfg.enabled) {
270
- console.log('[HttpLogging] Disabled by configuration');
271
- return;
272
- }
273
-
274
- if (cfg.requests.enabled) {
275
- app.use(this.requestLogger);
276
- }
277
-
278
- if (cfg.responses.enabled) {
279
- app.use(this.responseLogger);
280
- }
281
-
282
- console.log(`[HttpLogging] Enabled (requests: ${cfg.requests.enabled}, responses: ${cfg.responses.enabled}, bodies: ${cfg.requests.bodies})`);
283
- console.log(`[HttpLogging] Excluded paths: ${cfg.excludePaths.join(', ')}`);
284
- }
285
- };
286
- }
287
-
288
- module.exports = {
289
- createHttpLogging,
290
- createRequestLogger,
291
- createResponseLogger,
292
- mergeConfig,
293
- DEFAULT_CONFIG
294
- };
295
-