How to save winston log file into mysql database? - javascript

I've configured the winston logger like this :
import winston from "winston";
const { SqlTransport } = require("winston-sql-transport");
const transportConfig = {
client: "mysql2",
connection: {
host: "localhost",
user: "root",
password: "Mahdi54321",
database: "todos",
// port: "3307",
},
tableName: "logs",
};
const alignColorsAndTime = winston.format.combine(
winston.format.colorize({
all: true,
}),
winston.format.label({
label: "[LOGGER]",
}),
winston.format.timestamp({
format: "YYYY-MM-DD HH:mm:ss",
}),
winston.format.printf(
(info) => `${info.label} ${info.timestamp} ${info.level} : ${info.message}`
)
);
export const logger = winston.createLogger({
level: "debug",
transports: [
new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
alignColorsAndTime
),
}),
new winston.transports.File({
filename: "logs/example.log",
format: winston.format.combine(
winston.format.timestamp({
format: "YYYY-MM-DD HH:mm:ss",
}),
winston.format.json()
),
}),
new SqlTransport(transportConfig),
],
});
It only saves the first log and the next one is only saved in the file and not the database .
I'm guessing the new SqlTransport(transportConfig), doesn't run everytime so it can save every log to database .
How can I save every log one after another into mysql database ?

The package you use is deprecated, instead, you can use the winston-mysql package: https://www.npmjs.com/package/winston-mysql
implementation example as per documentation:
const options_default = {
host: 'localhost',
user: 'logger',
password: 'logger*test',
database: 'WinstonTest',
table: 'sys_logs_default'
};
//custom log table fields
const options_custom = {
host: 'localhost',
user: 'logger',
password: 'logger*test',
database: 'WinstonTest',
table: 'sys_logs_custom',
fields: {level: 'mylevel', meta: 'metadata', message: 'source', timestamp: 'addDate'}
};
//meta json log table fields
const options_json = {
host: 'localhost',
user: 'logger',
password: 'logger*test',
database: 'WinstonTest',
table: 'sys_logs_json'
};
const logger = winston.createLogger({
level: 'debug',
format: winston.format.json(),
defaultMeta: { service: 'user-service' },
transports: [
new winston.transports.Console({
format: winston.format.simple(),
}),
// or use: options_custom / options_json
new winstonMysql(options_default),
],
});
const rnd = Math.floor(Math.random() * 1000);
const msg = `test message ${rnd}`;
logger.debug(msg, {message: msg, type: 'demo'});
logger.error(msg, {message: msg, type: 'demo'});
logger.info(msg, {message: msg, type: 'demo'});
logger.warn(msg, {message: msg, type: 'demo'});

Related

Timezone Issue In Sequelize Nodejs

I want Sequelize to use my local time for reading and writing to database.
in Sequelize config file I added timezone: "+04:30", but it is just for writing in database.
for writing in database when i add
dialectOptions: {
useUTC: false, // -->Add this line. for reading from database
},
i get this error :
Ignoring invalid configuration option passed to Connection: useUTC. This is currently a warning, but in future versions of MySQL2, an error will be thrown if you pass an invalid configuration option to a Connection
full config file :
const Sequelize = require("sequelize");
const sequelize = new Sequelize("db", "root", "", {
dialect: "mysql",
port: process.env.SQL_PORT,
host: "localhost",
charset: "utf8",
collate: "utf8_persian_ci",
logging: false,
dialectOptions: {
useUTC: false, // -->Add this line. for reading from database
},
timezone: "+04:30",
});
Finally I fixed it by getter in my model:
createdAt: {
type: Sequelize.DATE,
defaultValue: moment(new Date()).format("YYYY-MM-DD HH:mm:ss"),
get: function () {
var isoDateString = new Date(this.getDataValue("createdAt"));
return new Date(
isoDateString.getTime() -
isoDateString.getTimezoneOffset() * 60 * 1000
);
},
},
and change my config file to :
const Sequelize = require("sequelize");
const sequelize = new Sequelize("db", "root", "", {
dialect: "mysql",
port: process.env.SQL_PORT,
host: "localhost",
charset: "utf8",
collate: "utf8_persian_ci",
logging: false,
timezone: "+04:30",
});

cannot read property FindAll() of undefined in node/express JS, existing mySQL DB

Good evening I'm getting this error in my express JS application and not sure how to resolve it.
I'm using an existing mySQL db and trying to retrieve items from my tbl_person table in myDB database. I'm pretty new to this, I'm not too sure what I'm doing incorrect. Some of the examples I'm seeing online is not entirely clear so I need some help.
Here is my sample code:
db.config.js
module.exports = {
HOST: "127.0.0.1",
USER: "root",
PASSWORD: "password",
DB: "myDB"
};
person.model.js
module.exports = (sequelize, DataTypes) => {
const Person = sequelize.define('tbl_person', {
personID: {
type: DataTypes.STRING(36),
field: 'personId',
allowNull: false,
primaryKey: true,
},
accountname: {
type: DataTypes.STRING(50),
field: 'accountname',
allowNull: true,
},
password: {
type: DataTypes.STRING(100),
field: 'password',
allowNull: true,
},
nameprefix: {
type: DataTypes.STRING(20),
field: 'nameprefix',
allowNull: true,
},
firstname: {
type: DataTypes.STRING(50),
field: 'firstname',
allowNull: true,
},
middlename: {
type: DataTypes.STRING(50),
field: 'middlename',
allowNull: true,
},
lastname: {
type: DataTypes.STRING(50),
field: 'lastname',
allowNull: true,
},
})
return Person;
};
person.controller.js
const person = require("../models/person.model.js").Person;
module.exports = {
getPersons(req, res) {
person.findAll({
where: { isActive : 1 },
}).then(person => {
res.status(201).json({
person: person,
success: true,
message: "get person request successful."
});
}).catch(error => {
console.error("get person request failed: ", error);
res.status(500).send({
success: false,
message: "get person request failed: " + error
});
})
}
};
index.js
const person = require("../controllers/person.controller.js");
module.exports = app => {
app.get("/api", (req, res) =>
res.status(200).send({
message: "Welcome to my API!",
})
);
// ========================= Person Routes ========================= //
app.get("/api/person/get", person.getPersons);
};
server.js
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
require("./routes/index.js")(app);
app.get("*", (req, res) => {
res.status(404).send({
status: false,
message: "No matching route!"
});
});
//PORTS
const port = process.env.PORT || 3000;
// set port, listen for requests
app.listen(port, () => {
console.log(`Server is running on port ${port}.`);
});
You should register all models and their associations before using them. And you should use them either from Sequelize instance or from your object holding all registered models.
See my answer here about how to register all models and associations.

Cannot read property 'findOrCreate' of undefined with sequelize-auto

I'm not really good at English and coding something. My OS is Mac and here is my basic info
dialect : mysql
sequelize-ver: 6.3.3
folder structure
I wrote my problem in the below on my question.
First, I imported .sql file to my database and i made models automatically from sequelize-auto, and also migrated automatically from sequelize-auto-migrate. ( I really appreciate about it. )
Here is my Mentors model ( I made signUp controller from this model. )
/* jshint indent: 2 */
// eslint-disable-next-line no-unused-vars
const { Model } = require('sequelize');
module.exports = function (sequelize, DataTypes) {
return sequelize.define('Mentors', {
id: {
autoIncrement: true,
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
},
mentor_name: {
type: DataTypes.STRING(255),
allowNull: true,
},
nickname: {
type: DataTypes.STRING(255),
allowNull: true,
},
email: {
type: DataTypes.STRING(255),
allowNull: true,
},
password: {
type: DataTypes.STRING(255),
allowNull: true,
},
sex: {
type: DataTypes.STRING(255),
allowNull: true,
},
phone: {
type: DataTypes.STRING(255),
allowNull: true,
},
birthday: {
type: DataTypes.STRING(255),
allowNull: true,
},
certification_path: {
type: DataTypes.STRING(255),
allowNull: true,
},
intro: {
type: DataTypes.STRING(255),
allowNull: true,
},
created_at: {
type: DataTypes.DATE,
allowNull: true,
},
}, {
sequelize,
tableName: 'Mentors',
});
};
and here is my model index.js
/* eslint-disable global-require */
/* eslint-disable import/no-dynamic-require */
// 'use strict';
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development'; // 환경변수 NODE_ENV를 설정 안 해줄 경우 test 객체 연결 정보로 DB 연결 설정
const config = require(__dirname, +'/../config/config.js')[env];
const db = {};
let sequelize;
if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
sequelize = new Sequelize(config.database, config.username, config.password, config);
}
fs
.readdirSync(__dirname)
.filter((file) => ((file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js')))
.forEach((file) => {
const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
db[model.name] = model;
});
Object.keys(db).forEach((modelName) => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
and last, here is my signUp controller
const { Mentors } = require('../../models/Mentors');
module.exports = {
post: (req, res) => {
const {
// eslint-disable-next-line camelcase
mentor_name, nickname, email, password, sex, phone, birthday, certification_path, intro,
} = req.body;
Mentors
.findOrCreate({
where: {
email,
},
defaults: {
mentor_name,
nickname,
password,
sex,
phone,
birthday,
certification_path,
intro,
},
})
// eslint-disable-next-line consistent-return
.then(async ([result, created]) => {
if (!created) {
return res.status(409).send('Already exists user');
}
const data = await result.get({ plain: true });
res.status(200).json(data);
}).catch((err) => {
res.status(500).send(err);
});
// console.log('/mentor/signup');
},
};
and now, I'm facing this error when I type 'npm start'
TypeError: Cannot read property 'findOrCreate' of undefined
error screenshot
I googled a lot because of this problem, but still can't find out solution...
please help me how to solve this problem.
here is my config.js
development: { // 배포할 때 RDS 연결 정보
username: 'root',
password: '(something)',
database: 'user',
host: 'localhost',
port: 3001,
dialect: 'mysql',
logging: false,
},
};
here is my app.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
const port = 3001;
// routes
const mentorRouter = require('./routes/mentor');
// const menteeRouter = require('./routes/mentee');
/*
* bodyparser.json() - body로 넘어온 데이터를 JSON 객체로 변환
*/
app.use(bodyParser.json());
/*
* bodyParser.urlencoded({ extended }) - 중첩 객체를 허용할지 말지를 결정하는 옵션
* 참고 링크(https://stackoverflow.com/questions/29960764/what-does-extended-mean-in-express-4-0/45690436#45690436)
*/
app.use(bodyParser.urlencoded({ extended: false }));
/*
* cors() - CORS를 대응하기 위한 라이브러리 ( Access-Control-Allow-Origin: * )
* https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
*/
app.use(
cors({
origin: ['http://localhost:3000'],
methods: ['GET', 'POST', 'PATCH'],
credentials: true,
}),
);
app.use('/mentor', mentorRouter);
// app.use('/mentee', menteeRouter);
app.set('port', port);
app.listen(app.get('port'), () => {
console.log(`app is listening in PORT ${app.get('port')}`);
});
// 나중 테스트 코드에서 쓰기 위해 export
module.exports = app;
change your import statement in controller to import model index file like this
const db = require('../../models');
and then use it like
db.Mentors.findOrCreate()

Mongoose Model is Not Saving, Not Throwing Error

My mongoose model (node/express app) is neither saving nor throwing an error and I do not know why...
Here is my model. It has a Post referencing many comments by schema ID:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var CommentSchema = new Schema({
body: {type: String, required: true, max: 2000},
created: { type: Date, default: Date.now },
flags: {type: Number, default: 0}
}, {
writeConcern: {
w: 0,
j: false,
wtimeout: 200
}
});
var PostSchema = new Schema({
body: {type: String, required: true, max: 2000},
created: { type: Date, default: Date.now },
flags: {type: Number, default: 0},
comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }]
}, {
writeConcern: {
w: 0,
j: false,
wtimeout: 200
}
});
var Post = mongoose.model('Post', PostSchema);
var Comment = mongoose.model('Comment', CommentSchema)
module.exports = {
Post: Post,
Comment: Comment
}
Here is my Route. It simply creates a post from the incoming body and attempts to save it. It references the exported post by model.Post as the exported module is an object.
var express = require('express');
var router = express.Router();
const fs = require('fs');
var model = require('../models/model');
router.post('/uploadPost', (req, res, next)=>{
console.log('inside /uploadPost')
console.log('value of req.files: ', req.files)
console.log('value of req.body: ', req.body)
var post = {
body: req.body.post,
created: Date.now(),
flags: 0,
comments: []
}
console.log('value of post: ', post)
let postInstance = new model.Post(post)
console.log('value of postInstance: ', postInstance)
postInstance.save().then(post=>{
console.log('value of post: ', post)
}).catch( (e) => {
console.log('There was an error', e.message);
});
res.json({return: 'return from /uploadPost'})
})
module.exports = router;
And here is my terminal output. It manages to console.log everything with the exception of either the save callback or the error. I thought it may have been a race condition with the res.json, so I put that in the callback, but that didn't do anything either. What is going on?
value of req.body: { post: 'lkjlkjlk' }
value of post: { body: 'lkjlkjlk',
created: 1552587547653,
flags: 0,
comments: [] }
value of postInstance: { flags: 0,
comments: [],
_id: 5c8a9b1ba7cece70037d3f46,
body: 'lkjlkjlk',
created: 2019-03-14T18:19:07.653Z }
EDIT:
I was connecting to mongoose wrong...sigh.
Here is a correct connection code (the above then is correct):
mongoose.connect("mongodb://localhost:27017/mydb");
mongoose.Promise = global.Promise;
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
db.once('open', function() {
// we're connected!
console.log('connected to mongoose db')
});

How to work with more than one sequelize DB connection in NestJS

I am using the example from the NestJS Documentation on how to setup the Sequelize DB connection. How can I setup connections to more than two databases using Sequelize and TypeScript for NestJS.
You can just setup multiple Sequelize connections in your databaseProviders:
export const databaseProviders = [
{
provide: 'SequelizeCatToken',
useFactory: async () => {
const sequelize = new Sequelize({
dialect: 'mysql',
host: 'localhost',
port: 3306,
username: 'catroot',
password: 'catpassword',
database: 'cats',
});
sequelize.addModels([Cat]);
await sequelize.sync();
return sequelize;
},
},
{
provide: 'SequelizeDogToken',
useFactory: async () => {
const sequelize = new Sequelize({
dialect: 'mysql',
host: 'localhost',
port: 3306,
username: 'doogroot',
password: 'dogpassword',
database: 'dogs',
});
sequelize.addModels([Dog]);
await sequelize.sync();
return sequelize;
},
},
];
You must use name for the connection, its mandatory.
const defaultOptions = {
dialect: 'postgres',
port: 5432,
username: 'user',
password: 'password',
database: 'db',
synchronize: true,
};
#Module({
imports: [
SequelizeModule.forRoot({
...defaultOptions,
host: 'user_db_host',
models: [User],
}),
SequelizeModule.forRoot({
...defaultOptions,
name: 'albumsConnection',
host: 'album_db_host',
models: [Album],
}),
],
})
export class AppModule {}
Here is the documentation in Nest

Categories

Resources