Parseable

JavaScript

Learn about JavaScript in Parseable, including core concepts, configuration steps, and practical guidance for building an effective observability workflow.


Parseable Bunyan Plugin

The Parseable Bunyan plugin is developed by our community champion Jacques-Yves Bleau. Refer to the plugin here:

NPM page: https://www.npmjs.com/package/parseable-bunyan Repo page: https://github.com/jybleau/parseable-node-loggers/tree/main/packages/bunyan#parseable-bunyan Installation

npm install parseable-bunyan
yarn add parseable-bunyan

Using the Plugin

const { ParseableBunyan } = require('parseable-bunyan')
const bunyan = require('bunyan')

const parseableStream = new ParseableBunyan({
    // highlight-start 
    url: process.env.PARSEABLE_URL, // Ex: 'https://parsable.myserver.local/api/v1/logstream'
    username: process.env.PARSEABLE_USERNAME,
    password: process.env.PARSEABLE_PASSWORD,
    logstream: process.env.PARSEABLE_LOGSTREAM, // The logstream name
    // highlight-end
    tags: { tag1: 'tagValue' } // optional tags to be added with each ingestion
    disableTLSCerts: true, // Optional: Default to false. Set to true to ignore invalid certificate
    http2: true, // Optional: Default to true. Set to false to use HTTP/1.1 instead of HTTP/2.0
    buffer: { maxEntries: 100, flushInterval: 5000 }, // Optional: Tune the default buffering options
    onError: error => console.error(error), // Optional: handle an error by yourself
    onRecord: record => { // optional onRecord event
        // Examples of what could be done here: exclude routes, methods, IPs and UAs
        const excludeMethods = 'HEAD,OPTIONS'
        const excludeRoutes = '/check,/test1'
        const excludeIPs = '192.168.1.1,192.168.1.2'
        const excludeUAs = 'UptimeRobot,AnnoyingUA'

        if (record.req) {
        if (excludeRoutes.includes(record.req.path)) {
            return false
        }
        if (excludeMethods.includes(record.req.method)) {
            return false
        }
        if (record.remoteAddress) {
            if (excludeIPs.some(ip => record.remoteAddress.includes(ip))) {
            return false
            }
        }            
        if (record.req.headers['user-agent']) {
            const _ua = record.req.headers['user-agent'].toLowerCase()
            if (excludeUAs.some(ua => _ua.includes(ua.toLowerCase()))) {
            return false
            }
        }
        }
    // You can also apply custom serialization here and return the serialized record.
  }
})

const bunyanLogger = bunyan.createLogger({
    name: 'logger',
    serializers, // optionally set your own serializers
    streams: [parseableStream]
  })

Parseable Winston Plugin

This is a community plugin, refer to the plugin here:

NPM page: https://www.npmjs.com/package/parseable-winston Repo page: https://github.com/jybleau/parseable-node-loggers/tree/main/packages/winston#parseable-winston

Installation

npm install parseable-winston
yarn add parseable-winston

Using the Plugin

// Using cjs
const { ParseableTransport } = require('parseable-winston')
const winston = require('winston')
// highlight-start 
const parseable = new ParseableTransport({
  url: process.env.PARSEABLE_LOGS_URL, // Ex: 'https://parsable.myserver.local/api/v1/logstream'
  username: process.env.PARSEABLE_LOGS_USERNAME,
  password: process.env.PARSEABLE_LOGS_PASSWORD,
  logstream: process.env.PARSEABLE_LOGS_LOGSTREAM, // The logstream name
  tags: { tag1: 'tagValue' } // optional tags to be added with each ingestion
})
// highlight-end

const logger = winston.createLogger({
  levels: winston.config.syslog.levels,
  transports: [parseable],
  defaultMeta: { instance: 'app', hostname: 'app1' }
})

logger.info('User took the goggles', { userid: 1, user: { name: 'Rainier Wolfcastle' } })
logger.warning('The goggles do nothing', { userid: 1 })

To turn off default buffering option:

const parseable = new ParseableTransport({
  url: process.env.PARSEABLE_LOGS_URL,
  username: process.env.PARSEABLE_LOGS_USERNAME,
  password: process.env.PARSEABLE_LOGS_PASSWORD,
  logstream: process.env.PARSEABLE_LOGS_LOGSTREAM,
  buffer: { maxEntries: 100, flushInterval: 5000 }
})

Using plain JavaScript

Create a dataset

First, we'll need to create a dataset. This is a one time operation, and we recommend storing log entries with same schema in a single dataset. So, for example, you can use one dataset per application (given that all logs from that application have the same schema).

var myHeaders = new Headers();
// highlight-start 
// TODO: Replace the basic auth credentials with your Parseable credentials
myHeaders.append("Authorization", "Basic YWRtaW46YWRtaW4=");
// highlight-end

var requestOptions = {
    method: 'PUT',
    headers: myHeaders,
    redirect: 'follow'
};
// highlight-start 
// TODO: Replace the url with your Parseable URL and dataset name
fetch("https://<parseable-url>/api/v1/logstream/<dataset-name>", requestOptions)
    // highlight-end
    .then(response => response.text())
    .then(result => console.log(result))
    .catch(error => console.log('error', error));

Send logs to the dataset

After dataset is created, you can start sending logs to the dataset using HTTP POST requests.

var myHeaders = new Headers();
// highlight-start
// INFO: Use X-P-META-<key>:<value> to add custom metadata to the log event
myHeaders.append("X-P-META-Host", "192.168.1.3");
// INFO: Use X-P-TAG-<key>:<value> to add tags to the log event
myHeaders.append("X-P-TAG-Language", "javascript");
// TODO: Replace the basic auth credentials with your Parseable credentials
myHeaders.append("Authorization", "Basic YWRtaW46YWRtaW4=");
// highlight-end
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify([{
    "id": "434a5f5e-2f5f-11ed-a261-asdasdafgdfd",
    "datetime": "24/Jun/2022:14:12:15 +0000",
    "host": "153.10.110.81",
    "user-identifier": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0",
    "method": "PUT",
    "status": 500,
    "referrer": "http://www.google.com/"
}]);

var requestOptions = {
    method: 'POST',
    headers: myHeaders,
    body: raw,
    redirect: 'follow'
};

// highlight-start
// TODO: Replace the url with your Parseable URL and dataset name
fetch("https://<parseable-url>/api/v1/logstream/<dataset-name>", requestOptions)
    // highlight-end
    .then(response => response.text())
    .then(result => console.log(result))
    .catch(error => console.log('error', error));

Querying a dataset

Once you have started sending logs to a dataset, you can query the logs using standard SQL.

var myHeaders = new Headers();
// highlight-start
// TODO: Replace the basic auth credentials with your Parseable credentials
myHeaders.append("Authorization", "Basic YWRtaW46YWRtaW4=");
// highlight-end
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({
    // highlight-start
    // TODO: Replace the dataset name with your dataset name
    "query": "select * from <dataset-name>",
    // TODO: Replace the time range with your desired time range
    "startTime": "2022-09-10T08:20:00+00:00",
    "endTime": "2022-09-10T08:20:31+00:00"
    // highlight-end
});

var requestOptions = {
    method: 'POST',
    headers: myHeaders,
    body: raw,
    redirect: 'follow'
};

// highlight-start
// TODO: Replace the url with your Parseable URL
fetch("https://<parseable-url>/api/v1/query", requestOptions)
    // highlight-end
    .then(response => response.text())
    .then(result => console.log(result))
    .catch(error => console.log('error', error));

Was this page helpful?

On this page