Skip to main content

2 posts tagged with "parseable"

View All Tags

· 2 min read
Surya Shakti

Introduction

Frontend developers also need logs to access vital information. When things go wrong in production environment, the lack of usage of proper logging in the app may cause a lot of problems. Frontend developers may not even know about some problems if there is no proper logging. Every backend application have some level of logging structure for various purposes but we rarely see any proper structural logging in frontend.

In this article we will learn how we can store logs of React.js application into parseable using Pino library.

Creating a react application

Let's start with creating a react application. To create a react application run this comman in the terminal

npx create-react-app my-project-demo

Initializing pino in the app

To install pino in your application run the following command

npm install pino

Now in your src folder make a directory named loggers where we will initialize pino.js which will send logs to parseable. In /loggers/index.js paste this following code.

import pino from "pino";

const send = async function (level, logEvent, a, b) {
const url = "https://demo.parseable.io/api/v1/logstream/pinotest2";

const response = await fetch(url, {
method: "POST",
headers: {
Authorization: "Basic cGFyc2VhYmxlOnBhcnNlYWJsZQ==",
"Content-Type": "application/json",
},
body: JSON.stringify([logEvent]),
});
console.log(response);
};

const logger = pino({
browser: {
serialize: true,
asObject: true,
transmit: {
send,
},
},
});

export default logger;

In the above peice of code we are creating a logger instance through which we will send the logs of the application to parseable. In send method we are collecting the logs of the application and sending them to the parseable.

Now to use this logger instance we have to import it where ever we need and use it in place of console.An exapmle is shown below

import logger from "./loggers";
logger.info("test log! pinotest2 stream from reactjs application.");
function App() {
return <div className="App">ReactJs logs to parseable</div>;
}
export default App;

Conslusion

You have successfuly integrated parseable with your react.js application. Now you can run your application and all the events you have replaced with logger will be posted to parseable and you can check in the logstream you created earlier.

Happy Coding 🥳🥳...

· 5 min read
Surya Shakti

Introduction

In this article we will learn how we can store logs of Node.js application into parseable using Winston library. We'll look at what is logging and why it is important.

Table of contents

  1. What is logging?
  2. Using winston in a Node.js application
  3. sending those logs to the parseable

What is logging?

Logging is the process of recording application events and data to a log file or any other sources, for the purpose of analysing the system.

Logs help developers to find the error, track the source of the bug and fix it. In Node.js it is critical to sturcture the application logs. when we are at the development phase we can use console.log to find the problems and to get the information you need.

But once the application is in production we cannot use the console.log any more.

Using winston in a Node.js application

I assume you have a node.js application, now to insall winston & winston-transport in your project run the following commands.

npm install winston
npm install winston-transport

Now our aim is to replace all the console messages from the application with the winston logger. So Just for example if you have these three event logs in your node.js application which you want to store in parseable using winston library.

connsole.warn('Got mutiple elements with same id');
console.error('Login Failed. Invalid ID');
console.info('Events posted successfully.');

Configuring Winston in Node.js app

Create a 'logger' folder in the root directory where we will configure winston and send the logs to parseable. Now in logger/index.js add following code

const winston = require("winston");
const { combine, timestamp, label, printf } = winston.format;
const Transport = require("winston-transport");
var axios = require("axios");

const myFormat = printf(({ level, message, label, timestamp }) => {
return JSON.stringify({
timestamp: timestamp,
level: level,
message: message,
});
});

class CustomTransport extends Transport {
constructor(opts) {
super(opts);
}
log(info, callback) {
console.info(info);
var data = JSON.stringify([info]);

var config = {
method: "post",
url: `https://demo.parseable.io/api/v1/logstream/${streamName}`,
headers: {
"X-P-META-Tag": "Owner",
"X-P-META-Tag": "Host",
"X-P-META-Tag": "Host.owner",
Authorization: `Basic ${key}`,
"Content-Type": "application/json",
},
data: data,
};

axios(config)
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});

callback();
}
}

const devLogger = () => {
const transport = new CustomTransport({});

return winston.createLogger({
level: "debug",
format: combine(label(), timestamp(), myFormat),
transports: [transport],
});
};


let logger = null;

if (process.env.NODE_ENV !== "production") {
logger = devLogger()
}

module.exports = logger;

Here we are configuring winston in our node.js applicationand sending the logs to parseable.

Let's discuss this code in parts for better understanding.

Initializing winston logger instance

const devLogger = () => {
const transport = new CustomTransport({});
return winston.createLogger({
level: "debug",
format: combine(label(), timestamp(), myFormat),
transports: [transport],
});
};

The snippet above contains the initialization of a Winston logger instance. Here we specify the log level for this specific logger instance using the npm log level standard, format in which logs will be stored and transport that specifies where the logs data will go. In our case we will send it to the parseable.

Setting custom format of the log data

const myFormat = printf(({ level, message, label, timestamp }) => {
return JSON.stringify({
timestamp: timestamp,
level: level,
message: message,
});
});

The snippet above specifies the format of the log data in which it will be stored.

Sending the log data to parseable

class CustomTransport extends Transport {
constructor(opts) {
super(opts);
}
log(info, callback) {
console.info(info);
var data = JSON.stringify([info]);
var config = {
method: "post",
url: `https://demo.parseable.io/api/v1/logstream/${streamName}`,
headers: {
"X-P-META-Tag": "Owner",
"X-P-META-Tag": "Host",
"X-P-META-Tag": "Host.owner",
Authorization: `Basic ${key}`,
"Content-Type": "application/json",
},
data: data,
};
axios(config)
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
callback();
}
}

The snippet above is responsible for sending the log data to the parseable. here streamName is the log stream you have created in parseable. and the key is the authentication key for accessing the parseable.

calling the logger function

let logger = null;
if (process.env.NODE_ENV !== "production") {
logger = devLogger()
}

You may not want to store the logs in parseable in development phase then you can see them on console to test it and when in production mode you can send it to parseable. The snippet above calls the logger function according to your requirements. you can also call th efunction directly if you dont want this conditional calling.

Then we can use logger instead of console in our application.

const logger = require('./logger')

logger.warn('Got mutiple elements with same id')
logger.error('Login Failed. Invalid ID')
logger.info('Events posted successfully.')

Conslusion

Hurray!!🥳🥳🥳

You have successfuly integrated parseable with your node.js application. now you can run your application and all the events you have replaced with logger will be posted to parseable and you can check in the logstream you created earlier.