Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

errsole

Package Overview
Dependencies
Maintainers
1
Versions
87
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

errsole - npm Package Compare versions

Comparing version 2.7.0 to 2.8.0

examples/proxy-middleware/hapi-custom-path.js

93

docs/proxy-middleware-configuration.md

@@ -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;

52

lib/main/server/controllers/logController.js

@@ -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

lib/main/server/utils/jsonapiUtil.js

@@ -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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc