Comparing version 2.7.0 to 2.8.0
@@ -17,3 +17,5 @@ # Proxy Middleware Configuration | ||
* [Fastify](#fastify) | ||
* [Hapi](#hapi) | ||
* [Koa](#koa) | ||
* [Nest](#nest) | ||
@@ -91,2 +93,49 @@ ### Express | ||
### Hapi | ||
```javascript | ||
'use strict'; | ||
const Hapi = require('@hapi/hapi'); | ||
const errsole = require('errsole'); | ||
const ErrsoleSequelize = require('errsole-sequelize'); | ||
// Insert the Errsole code snippet at the beginning of your app's main file | ||
errsole.initialize({ | ||
storage: new ErrsoleSequelize({ | ||
dialect: 'sqlite', | ||
storage: '/tmp/logs.sqlite' | ||
}) | ||
}); | ||
const init = async () => { | ||
const server = Hapi.server({ | ||
port: 3000, | ||
host: 'localhost' | ||
}); | ||
// Register the Errsole Proxy Middleware at the desired path (e.g., /errsole) | ||
// Make sure this is the first plugin to be registered | ||
await server.register({ | ||
plugin: errsole.hapiProxyMiddleware('/errsole') | ||
}); | ||
// Register other plugin below the Errsole Proxy Middleware | ||
await server.start(); | ||
console.log('Server running on %s', server.info.uri); | ||
}; | ||
process.on('unhandledRejection', (err) => { | ||
console.log(err); | ||
process.exit(1); | ||
}); | ||
init(); | ||
``` | ||
#### Note | ||
If you have initialized Errsole with a custom path, you need to append this custom path to the middleware path: [Code Example](/examples/proxy-middleware/hapi-custom-path.js) | ||
### Koa | ||
@@ -136,4 +185,48 @@ | ||
### Nest | ||
```javascript | ||
import { NestFactory } from '@nestjs/core'; | ||
import * as bodyParser from 'body-parser'; | ||
import errsole from 'errsole'; | ||
import ErrsoleSequelize from 'errsole-sequelize'; | ||
import { AppModule } from './app.module'; | ||
// Insert the Errsole code snippet at the beginning of your app's main file | ||
errsole.initialize({ | ||
storage: new ErrsoleSequelize({ | ||
dialect: 'sqlite', | ||
storage: '/tmp/logs.sqlite' | ||
}) | ||
}); | ||
async function bootstrap () { | ||
const app = await NestFactory.create(AppModule); | ||
// Register the Errsole Proxy Middleware at the desired path (e.g., /errsole) | ||
// Make sure this is the first middleware used | ||
// Use body-parser middleware if NestJS is using Express | ||
app.use(bodyParser.json()); | ||
app.use('/errsole', (req, res, next) => { | ||
errsole.nestExpressProxyMiddleware('/errsole', req, res, next); | ||
}); | ||
// For Fastify, use the following middleware | ||
// app.use('/errsole', (req, res, next) => { | ||
// errsole.nestFastifyProxyMiddleware('/errsole', req, res); | ||
// }); | ||
// Add other middlewares below the Errsole Proxy Middleware | ||
await app.listen(3000); | ||
} | ||
bootstrap(); | ||
``` | ||
#### Note | ||
If you have initialized Errsole with a custom path, you need to append this custom path to the middleware path: [Code Example](/examples/proxy-middleware/nest-custom-path.ts) | ||
## Main Documentation | ||
[Main Documentation](/README.md) |
@@ -6,2 +6,3 @@ 'use strict'; | ||
const util = require('util'); | ||
const http = require('http'); | ||
const ErrsoleMain = require('./main'); | ||
@@ -95,3 +96,95 @@ const Errsole = { | ||
}; | ||
Errsole.nestExpressProxyMiddleware = function (path, req, res, next) { | ||
const options = { | ||
hostname: 'localhost', | ||
port: this.port, | ||
path: req.url.replace(path, ''), | ||
method: req.method, | ||
headers: { | ||
...req.headers, | ||
host: 'localhost:' + this.port | ||
} | ||
}; | ||
const proxyReq = http.request(options, (proxyRes) => { | ||
if (proxyRes.statusCode && proxyRes.headers) { | ||
res.writeHead(proxyRes.statusCode, proxyRes.headers); | ||
} | ||
proxyRes.pipe(res, { end: true }); | ||
}); | ||
proxyReq.on('error', (err) => { | ||
res.status(500).send('Proxy request error' + err); | ||
}); | ||
if (req.method === 'POST' && req.body) { | ||
const bodyData = JSON.stringify(req.body); | ||
proxyReq.setHeader('Content-Type', 'application/json'); | ||
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData)); | ||
proxyReq.write(bodyData); | ||
} | ||
proxyReq.end(); | ||
}; | ||
Errsole.nestFastifyProxyMiddleware = function (path, req, res) { | ||
const bodyChunks = []; | ||
req.raw.on('data', chunk => { | ||
bodyChunks.push(chunk); | ||
}); | ||
req.raw.on('end', () => { | ||
const bodyData = Buffer.concat(bodyChunks).toString(); | ||
const options = { | ||
hostname: 'localhost', | ||
port: this.port, | ||
path: req.url.replace(path, ''), | ||
method: req.method, | ||
headers: { | ||
...req.headers, | ||
host: 'localhost:' + this.port | ||
} | ||
}; | ||
const proxyReq = http.request(options, (proxyRes) => { | ||
if (proxyRes.statusCode && proxyRes.headers) { | ||
res.raw.writeHead(proxyRes.statusCode, proxyRes.headers); | ||
} | ||
proxyRes.pipe(res.raw, { end: true }); | ||
}); | ||
proxyReq.on('error', (err) => { | ||
res.status(500).send('Proxy request error: ' + err); | ||
}); | ||
if (req.method === 'POST' && bodyData) { | ||
proxyReq.setHeader('Content-Type', 'application/json'); | ||
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData)); | ||
proxyReq.write(bodyData); | ||
} | ||
proxyReq.end(); | ||
}); | ||
}; | ||
Errsole.hapiProxyMiddleware = function (basePath) { | ||
const initializedPath = this.path || ''; | ||
const targetURL = 'http://localhost:' + this.port; | ||
return { | ||
name: 'hapiPorxyMiddleware', | ||
register: async function (server) { | ||
const fullPath = `${basePath}${initializedPath}/{param*}`; | ||
server.route({ | ||
method: 'GET', | ||
path: fullPath, | ||
handler: (request, h) => { | ||
const pathSuffix = request.params.param ? '/' + request.params.param : ''; | ||
const fullTargetURL = `${targetURL}${initializedPath}${pathSuffix}`; | ||
return h.redirect(fullTargetURL); | ||
} | ||
}); | ||
} | ||
}; | ||
}; | ||
module.exports = Errsole; |
@@ -12,2 +12,5 @@ const Jsonapi = require('../utils/jsonapiUtil'); | ||
} | ||
if (query.limit) { | ||
query.limit = parseInt(query.limit); | ||
} | ||
if (query.levels) { | ||
@@ -30,3 +33,3 @@ query.levels = query.levels.split(',').map((item) => item.trim()); | ||
if (logs && logs.items) { | ||
res.send(Jsonapi.Serializer.serialize(Jsonapi.UserType, logs.items)); | ||
res.send(Jsonapi.Serializer.serialize(Jsonapi.LogType, logs.items, logs.filters)); | ||
} else { | ||
@@ -59,3 +62,3 @@ const errorData = [ | ||
if (result && result.item) { | ||
res.send(Jsonapi.Serializer.serialize(Jsonapi.UserType, result.item)); | ||
res.send(Jsonapi.Serializer.serialize(Jsonapi.LogType, result.item)); | ||
} else { | ||
@@ -91,3 +94,3 @@ const errorData = [ | ||
await storageConnection.ensureLogsTTL(); | ||
res.send(Jsonapi.Serializer.serialize(Jsonapi.UserType, result.item)); | ||
res.send(Jsonapi.Serializer.serialize(Jsonapi.LogType, result.item)); | ||
} else { | ||
@@ -123,1 +126,44 @@ const errorData = [ | ||
}; | ||
exports.getLogMeta = async (req, res) => { | ||
const logId = req.params.logId; | ||
try { | ||
if (logId) { | ||
const storageConnection = getStorageConnection(); | ||
const result = await storageConnection.getMeta(logId); | ||
if (result && result.item) { | ||
res.send(Jsonapi.Serializer.serialize(Jsonapi.LogType, result.item)); | ||
} else { | ||
const errorData = [ | ||
{ | ||
error: 'Bad Request', | ||
message: 'invalid request' | ||
} | ||
]; | ||
res.status(400).send({ errors: errorData }); | ||
} | ||
} else { | ||
const errorData = [ | ||
{ | ||
error: 'Bad Request', | ||
message: 'invalid request' | ||
} | ||
]; | ||
res.status(400).send({ errors: errorData }); | ||
} | ||
} catch (error) { | ||
console.error(error); | ||
if (error.message === 'storageConnection.getMeta is not a function') { | ||
res.send(Jsonapi.Serializer.serialize(Jsonapi.LogType, { id: logId, meta: '{}' })); | ||
} else { | ||
res.status(500).send({ | ||
errors: [ | ||
{ | ||
error: 'Internal Server Error', | ||
message: 'An unexpected error occurred' | ||
} | ||
] | ||
}); | ||
} | ||
} | ||
}; |
@@ -32,2 +32,3 @@ const express = require('express'); | ||
router.get('/api/logs', auth.authenticateToken, logController.getLogs); | ||
router.get('/api/logs/:logId/meta', auth.authenticateToken, logController.getLogMeta); | ||
router.get('/api/logs/config/ttl', auth.authenticateTokenWithAdmin, logController.getLogsTTL); | ||
@@ -34,0 +35,0 @@ router.patch('/api/logs/config/ttl', auth.authenticateTokenWithAdmin, logController.updateLogsTTL); |
@@ -9,10 +9,11 @@ const JSONAPISerializer = require('json-api-serializer'); | ||
Jsonapi.UserType = 'users'; | ||
Jsonapi.Logs = 'logs'; | ||
Jsonapi.AppType = 'apps'; | ||
Jsonapi.LogType = 'logs'; | ||
Serializer.register(Jsonapi.UserType, {}); | ||
Serializer.register(Jsonapi.AppType, {}); | ||
Serializer.register(Jsonapi.Logs, { | ||
topLevelMeta: function (data, meta) { | ||
Serializer.register(Jsonapi.LogType, { | ||
topLevelMeta: function (data, filters) { | ||
return { | ||
total: meta.count | ||
filters | ||
}; | ||
@@ -19,0 +20,0 @@ } |
{ | ||
"name": "errsole", | ||
"version": "2.7.0", | ||
"version": "2.8.0", | ||
"description": "Logger with a Built-in Web Dashboard", | ||
@@ -42,3 +42,2 @@ "keywords": [ | ||
"nodemailer": "^6.9.13", | ||
"react-json-view": "^1.21.3", | ||
"strip-ansi": "^6.0.1", | ||
@@ -48,2 +47,3 @@ "uuid": "^9.0.1" | ||
"devDependencies": { | ||
"@babel/core": "^7.24.5", | ||
"@babel/preset-env": "^7.24.0", | ||
@@ -60,4 +60,6 @@ "@babel/preset-react": "^7.23.3", | ||
"history": "^4.10.1", | ||
"moment": "^2.30.1", | ||
"react": "^16.8.6", | ||
"react-dom": "^16.8.6", | ||
"react-json-view": "^1.21.3", | ||
"react-redux": "^7.0.3", | ||
@@ -64,0 +66,0 @@ "react-router-dom": "^5.0.1", |
@@ -113,3 +113,19 @@ <p align="center"> | ||
``` | ||
### meta | ||
In Errsole's custom logger, you can include metadata with your logs. This metadata can be any contextual information, such as HTTP requests or database query results. In the Errsole Web Dashboard, you can view this metadata in a clean JSON viewer without cluttering the log messages. | ||
To include metadata in your logs, use the `meta` function followed by the appropriate logging function (error, log, etc.). | ||
#### Example | ||
```javascript | ||
errsole.meta({ reqBody: req.body, queryResults: results }).error(err); | ||
errsole.meta({ email: req.body.email }).log('User logged in'); | ||
``` | ||
#### Note | ||
The `meta` function must be the first function in the chain, followed by the desired logging function. | ||
## Contribution and Support | ||
@@ -116,0 +132,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
3271874
11
47
2314
139
25
3
- Removedreact-json-view@^1.21.3
- Removed@babel/runtime@7.26.0(transitive)
- Removedasap@2.0.6(transitive)
- Removedbase16@1.0.0(transitive)
- Removedcross-fetch@3.1.8(transitive)
- Removedfbemitter@3.0.0(transitive)
- Removedfbjs@3.0.5(transitive)
- Removedfbjs-css-vars@1.0.2(transitive)
- Removedflux@4.0.4(transitive)
- Removedjs-tokens@4.0.0(transitive)
- Removedlodash.curry@4.1.1(transitive)
- Removedlodash.flow@3.5.0(transitive)
- Removedloose-envify@1.4.0(transitive)
- Removednode-fetch@2.7.0(transitive)
- Removedobject-assign@4.1.1(transitive)
- Removedpromise@7.3.1(transitive)
- Removedpure-color@1.3.0(transitive)
- Removedreact@17.0.2(transitive)
- Removedreact-base16-styling@0.6.0(transitive)
- Removedreact-dom@17.0.2(transitive)
- Removedreact-json-view@1.21.3(transitive)
- Removedreact-lifecycles-compat@3.0.4(transitive)
- Removedreact-textarea-autosize@8.5.5(transitive)
- Removedregenerator-runtime@0.14.1(transitive)
- Removedscheduler@0.20.2(transitive)
- Removedtr46@0.0.3(transitive)
- Removedua-parser-js@1.0.39(transitive)
- Removeduse-composed-ref@1.3.0(transitive)
- Removeduse-isomorphic-layout-effect@1.1.2(transitive)
- Removeduse-latest@1.2.1(transitive)
- Removedwebidl-conversions@3.0.1(transitive)
- Removedwhatwg-url@5.0.0(transitive)