Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
GOV_INFRASTRUCTURE=./infrastructure.yaml
GOV_CONFIG_PRUEBA_test=Modified312312
GOV_CONFIG_PRUEBA_test=Modified312312
GOV_LOG_MONGODB_ENABLED=false
GOV_LOG_MONGODB_URI=mongodb://root:root@localhost:27017/logs?authSource=admin
GOV_LOG_MONGODB_LEVEL=INFO
44 changes: 24 additions & 20 deletions .github/workflows/nodejs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
node-version: ['22']
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
Expand All @@ -38,6 +39,7 @@ jobs:
# github-token: ${{ secrets.GITHUB_TOKEN }}
# env:
# CI: true

npmReleaseDev:
name: (Develop) Publish new release to npm registry
runs-on: ubuntu-latest
Expand All @@ -49,16 +51,17 @@ jobs:
run: |
git config user.name $GITHUB_ACTOR
git config user.email gh-actions-${GITHUB_ACTOR}@github.com
- uses: actions/setup-node@v2
- uses: actions/setup-node@v4
with:
node-version: '14.x'
node-version: '22'
registry-url: 'https://registry.npmjs.org'
- run: npm version prerelease -m "Governify Commons version %s released"
- run: npm install
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- run: git push

githubRelease:
name: Release new version to GitHub
runs-on: ubuntu-latest
Expand Down Expand Up @@ -94,19 +97,20 @@ jobs:
pr_assignee: "alesancor1"
pr_label: "auto-pr"
github_token: ${{ secrets.GITHUB_TOKEN }}

npmReleaseMain:
name: (Main) Publish new release to npm registry
needs: githubRelease
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: 'main'
- uses: actions/setup-node@v2
with:
node-version: '14.x'
registry-url: 'https://registry.npmjs.org'
- run: npm install
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
name: (Main) Publish new release to npm registry
needs: githubRelease
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: 'main'
- uses: actions/setup-node@v4
with:
node-version: '22'
registry-url: 'https://registry.npmjs.org'
- run: npm install
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
## [1.21.1](https://github.com/governify/commons/compare/v1.21.0...v1.21.1) (2025-08-07)


### Bug Fixes

* remove extra space in log type formatting ([6227676](https://github.com/governify/commons/commit/622767650a00cc72c2b52ba7dc49ba577ed4bcb8))



# [1.21.0](https://github.com/governify/commons/compare/v1.19.0...v1.21.0) (2025-05-20)


### Features

* **logger:** add MongoDB transport ([b861a17](https://github.com/governify/commons/commit/b861a17a21b55d53ec226cb4f94fe092544f903a))



# [1.19.0](https://github.com/governify/commons/compare/v1.18.0...v1.19.0) (2023-07-05)


Expand Down
124 changes: 105 additions & 19 deletions logger/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ const { combine, timestamp, printf } = format;
const fs = require('fs');
let servicePackage = JSON.parse(fs.readFileSync(__dirname + '/../package.json'));
require('winston-daily-rotate-file');
const MongoTransport = require('./mongo-transport');

function Logger(tags = []) {
this.tags = tags || [];
}

const myFormat = printf(({ level, message, tracing, label, timestamp }) => {
return `${JSON.stringify({date: timestamp, level: level,trace: tracing, labels: label, msg: message})}`;
});
});

const cloneInstance = (logger) =>{
return new Logger([...logger.tags]); //Clone the array to let the original unmodified
return new Logger([...logger.tags]); //Clone the array to leave the original unmodified
}

const LogType = {
Expand Down Expand Up @@ -44,6 +45,11 @@ let logConfig = {
storage: {
active: process.env.GOV_LOG_STORAGE ?? false,
level: LogLevel[process.env.GOV_LOG_STORAGE_LEVEL?.toUpperCase()] ?? (logLevelEnv ?? LogLevel.INFO)
},
mongodb: {
active: process.env.GOV_LOG_MONGODB_ENABLED === 'true' || false,
uri: process.env.GOV_LOG_MONGODB_URI || 'mongodb://root:root@localhost:27017/logs?authSource=admin',
level: LogLevel[process.env.GOV_LOG_MONGODB_LEVEL?.toUpperCase()] ?? (logLevelEnv ?? LogLevel.INFO)
}
}

Expand All @@ -54,8 +60,17 @@ const fileLogger = createLogger({
format: combine(
timestamp(),
myFormat
)
});
)
});

if (logConfig.mongodb.active) {
MongoTransport.initialize(logConfig.mongodb, servicePackage.name)
.then(success => {
if (success) {
fileLogger.add(MongoTransport.createTransport(servicePackage.name));
}
});
}

Logger.prototype.addPermanentTags = function(tags){
if (!(tags instanceof Array)){
Expand All @@ -66,54 +81,64 @@ Logger.prototype.addPermanentTags = function(tags){
}

Logger.prototype.debug = function(...msg){

if (logConfig.storage.active && LogLevel.DEBUG >= logConfig.storage.level){
fileLogger.debug(this.getWinstonMessage(...msg));
}
if (logConfig.mongodb.active && LogLevel.DEBUG >= logConfig.mongodb.level) {
fileLogger.debug(this.getWinstonMessage(...msg));
}
if (LogLevel.DEBUG < logConfig.level){
return;
}
console.debug(this.getMessageFormatted(LogType.DEBUG, ...msg))
}

Logger.prototype.info = function(...msg) {

if (logConfig.storage.active && LogLevel.INFO >= logConfig.storage.level){
fileLogger.info(this.getWinstonMessage(...msg));
}
if (logConfig.mongodb.active && LogLevel.INFO >= logConfig.mongodb.level) {
fileLogger.info(this.getWinstonMessage(...msg));
}
if (LogLevel.INFO < logConfig.level){
return;
}
console.info(this.getMessageFormatted(LogType.INFO, ...msg))
}

Logger.prototype.error = function(...msg) {

if (logConfig.storage.active && LogLevel.ERROR >= logConfig.storage.level){
fileLogger.error(this.getWinstonMessage(...msg));
}
if (logConfig.mongodb.active && LogLevel.ERROR >= logConfig.mongodb.level) {
fileLogger.error(this.getWinstonMessage(...msg));
}
if (LogLevel.ERROR < logConfig.level){
return;
}
console.error(this.getMessageFormatted(LogType.ERROR, ...msg))
}

Logger.prototype.warn = function(...msg) {

if (logConfig.storage.active && LogLevel.WARN >= logConfig.storage.level){
fileLogger.warn(this.getWinstonMessage(...msg));
}
if (logConfig.mongodb.active && LogLevel.WARN >= logConfig.mongodb.level) {
fileLogger.warn(this.getWinstonMessage(...msg));
}
if (LogLevel.WARN < logConfig.level){
return;
}
console.warn(this.getMessageFormatted(LogType.WARN, ...msg))
}

Logger.prototype.fatal = function(...msg) {

if (logConfig.storage.active && LogLevel.FATAL >= logConfig.storage.level){
fileLogger.error(this.getWinstonMessage(...msg));
}
if (logConfig.mongodb.active && LogLevel.FATAL >= logConfig.mongodb.level) {
fileLogger.error(this.getWinstonMessage(...msg));
}
if (LogLevel.FATAL < logConfig.level){
return;
}
Expand Down Expand Up @@ -145,7 +170,6 @@ Logger.prototype.getMessageFormatted = function(type, ...msg) {
return finalMsg;
}


const Theme = {
TRACEID: chalk.hex("#606C38"),
INFO: chalk.hex("#0077B6"),
Expand All @@ -158,14 +182,12 @@ const Theme = {
DEFAULT: chalk.white()
}



function getLogConfig(){
return logConfig;
}

function setLogConfig(newConfig){

// Handle file storage config changes
if((newConfig.storage.active && newConfig.storage.active !== logConfig.storage.active)){
fileLogger.clear();
const files = new transports.DailyRotateFile({
Expand All @@ -175,14 +197,36 @@ function setLogConfig(newConfig){
maxSize:sizeMaxMB + 'm',
maxFiles:nFiles,
level:'debug'
});
});
fileLogger.add(files);
}

// Handle MongoDB config changes
if (newConfig.mongodb.active !== logConfig.mongodb.active ||
(newConfig.mongodb.active && newConfig.mongodb.uri !== logConfig.mongodb.uri)) {

// Reconfigure MongoDB
MongoTransport.initialize(newConfig.mongodb, servicePackage.name)
.then(success => {
if (success) {
// Remove existing transport if any
fileLogger.transports.forEach((transport, i) => {
if (transport.name === 'mongodb') {
fileLogger.transports.splice(i, 1);
}
});

// Add new transport if enabled
if (newConfig.mongodb.active) {
fileLogger.add(MongoTransport.createTransport(servicePackage.name));
}
}
});
}

logConfig = newConfig;
}


function coloredTraceId() {
return Theme.TRACEID("[" + governify.tracer.getCurrentTraceShortId() + "] ");
}
Expand All @@ -192,11 +236,11 @@ function coloredType(type) {
case LogType.DEBUG:
return Theme.DEBUG("[" + type + "] ")
case LogType.INFO:
return Theme.INFO("[" + type + " ] ")
return Theme.INFO("[" + type + "] ")
case LogType.ERROR:
return Theme.ERROR("[" + type + "] ")
case LogType.WARN:
return Theme.WARN("[" + type + " ] ")
return Theme.WARN("[" + type + "] ")
case LogType.FATAL:
return Theme.FATAL("[" + type + "] ")
default:
Expand All @@ -205,9 +249,51 @@ function coloredType(type) {
}

Logger.prototype.getWinstonMessage = function (...msg) {
return {label:this.tags,tracing:governify.tracer.getCurrentTraceShortId(),message:msg.toString()}
// Process the message to extract useful information
const message = msg.join(' ');

// Convert tags to expected format
const tags = this.tags || [];

// Detect if it's an HTTP error message
let statusCode = null;
let url = null;

if (message.includes('Failed when calling service from Governify:')) {
// Extract HTTP error information if available
const urlMatch = message.match(/https?:\/\/[^\s]+/);
if (urlMatch) {
url = urlMatch[0].trim();

// Add http-request tag if it doesn't already exist
if (!tags.includes('http-request')) {
tags.push('http-request');
}

// Try to extract status code if present in the message
const statusMatch = message.match(/status(?:Code)?[:\s]+(\d+)/i);
if (statusMatch && statusMatch[1]) {
statusCode = parseInt(statusMatch[1], 10);
}
}
}

return {
label: tags,
tracing: governify.tracer.getCurrentTraceShortId(),
message: message,
statusCode: statusCode,
url: url
};
}

// Graceful shutdown to close connections
process.on('SIGINT', async () => {
await MongoTransport.shutDown();
process.exit(0);
});

module.exports = Logger;
module.exports.getLogConfig = getLogConfig;
module.exports.setLogConfig = setLogConfig;
module.exports.setLogConfig = setLogConfig;
module.exports.mongoTransport = MongoTransport;
Loading