An open API service indexing awesome lists of open source software.

https://github.com/teragrep/rlp_02

Teragrep RELP client for JavaScript
https://github.com/teragrep/rlp_02

javascript nodejs relp relp-client syslog syslog-client teragrep

Last synced: 2 months ago
JSON representation

Teragrep RELP client for JavaScript

Awesome Lists containing this project

README

        

image::https://avatars.githubusercontent.com/u/71876378?s=200&v=4[Teragrep Logo]

image::https://scan.coverity.com/projects/24236/badge.svg[Coverity Scan Build Status, link="https://scan.coverity.com/projects/teragrep-rlp_02"]

= RLP_02

rlp_02 minimal implementation of the RELP protocol using NodeJS.
This embraces similar implementation of his big brother RLP-01 java library.

* https://github.com/teragrep/rlp_01[Java implementation]

== Specs

https://github.com/rsyslog/librelp/blob/master/doc/relp.html[Specs Link]

== Documentation

See the official documentation on https://docs.teragrep.com[docs.teragrep.com].

== Install

[source,npm]
----
npm install @teragrep/rlp_02
----

== Importing modules

Supporting from version "@teragrep/rlp_02": "^1.0.19-rc12"

[source,javascript]
----
const { RelpConnection, RelpBatch, RelpRequest, RelpBatch, RelpWindow } = require('@teragrep/rlp_02')
----

== Test

The Maven build executes the test goal. Karma is a testing harness that is configured to jasmine framework.

Jasmine async works completely control the asynchronus behaviour.

== Example Relp Connection and Commit configuration

[source,javascript]
----
// Load the required modules

var config = require('dotenv');
const RelpConnection = require("../../main/js/RelpConnection")
const async = require('async');
const RelpRequest = require('../../main/js/RelpRequest');
const RelpBatch = require('../../main/js/RelpBatch');
const RelpWindow = require('../../main/js/RelpWindow');

// Syslog message for the RelpServer
let data = Buffer.from('<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - su root failed for lonvick on /dev/pts/8\n', 'ascii');
let invalidData = Buffer.from('<344565>5 2003-08-24T05:14:15.000000003-07:00 mymachine.example.com su - ID47 - su root failed for lonvick on /dev/pts/8\n', 'ascii'); // This contains the invalid PRI value
let sampleData = Buffer.from('<165>1 2003-10-11T22:14:15.003Z mymachine.example.comevntslog - ID47 [exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"] BOMAn applicationevent log entry...\n','ascii');

// Set up the connection and commit messages. adjust the port according to the needs.

let relpConnection = new RelpConnection();
let host = '127.0.0.1';
let port = 1337;
let cfePort = 1601;

// Configure the connection
async function connect() {
let conn = await relpConnection.connect(cfePort, host);
return conn;
}

async function disconnect(state) {
if(state){
await relpConnection.disconnect();
}
else {
console.log('Check the connection...')
}

}
/**
* Jasmine async works handles the asynchronus execution
* */
beforeEach(async function() {
let conn = await connect();
await commit(conn)
await disconnect()
})

function commit(){

return new Promise(async(resolve, reject) => {

let relpBatch = new RelpBatch();
relpBatch.insert(data);
relpBatch.insert(data);
relpBatch.insert(data);
relpBatch.insert(data);
console.log(relpBatch);

let resWindow = await relpConnection.commit(relpBatch);
console.log('After Batch-1 Completion....', resWindow)


let notSent = (resWindow === true) ? true : false; //Test purpose

//a commit promise to return rsp for each of the msgs that are in the batch or fail the commit promise.

while(notSent){

let res = await relpBatch.verifyTransactionAllPromise(); //
if(res){
notSent = false;
console.log('VerifyTransactionAllPromise......', res);
resolve(true);
}
else{
reject(false);
}
}

let relpBatch2 = new RelpBatch();

relpBatch2.insert(data2);
relpBatch2.insert(invalidData);
relpBatch2.insert(data2);
relpBatch2.insert(invalidData);
relpBatch2.insert(data2);
relpBatch2.insert(invalidData);
relpBatch2.insert(data2);
relpBatch2.insert(invalidData);
//relpBatch2.insert(sampleData);

// Commit the messages
relpConnection.commit(relpBatch2);
return resolve(true);
})
}
----

== Usage of our RLP_02 RelpConnection with RLO_08 component

[source,javascript]
----
/*
* Note: This is ONLY shown the part of necessary code snippets.
* In this demo, we use Relp Logging Out component generates the Syslog message,
* then using RLP_02 component to setup the connection to our Java-Relp-Server-Demo
* application.
*/
let relpConnection;
const host = 'localhost';
const port = 1601;

/*
* Setup the relp connection to the Java-Relp-Demo application
* which in this use case configure to running on port 1601
*/
async function setupConnection(port, host){
return new Promise(async (resolve, reject) => {
relpConnection = new RelpConnection();
let conn = await relpConnection.connect(port, host);
console.log('Connectig...',host,' at PORT ', port)
resolve(relpConnection)
})
}

/*
* This ensures to confirm the connection on the request, setup the relpconnection
*
*/
server.on("request", async(req, res) => {
await setupConnection(port, host) //
if(req.url == '/'){
return getHome(req, res)
}
else if(req.url == "/ua"){
return getUA(req, res)
}
})
/*
* Endpoint for access to the generated response with user agent and syslog message
*/
async function getUA(req, res){

const userAgent = req.headers['user-agent']
const ip = req.headers['x-real-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddres || req.socket.remoteAddress || '';

// Set response header
res.writeHead(200, { 'Content-Type': 'text/html' });
const dateTimestamp = '2014-07-24T17:57:36+03:00';
const timestamp = (new Date(dateTimestamp)).getTime();

let message = new SyslogMessage.Builder()
.withAppName('bulk-data-sorted') //valid
.withHostname(ip)
.withFacility(Facility.LOCAL0)
.withSeverity(Severity.INFORMATIONAL)
.withProcId('8740')
.withMsgId('ID47')
.withMsg(userAgent)
.withSDElement(new SDElement("exampleSDID@32473", new SDParam("iut", "3"), new SDParam("eventSource", "Application")))
.withDebug(true)
.build()

let rfc5424message;
rfc5424message = await message.toRfc5424SyslogMessage();
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write(rfc5424message.toString(), 'utf-8', async() => {
await commit(rfc5424message)
});
res.end(); //end the response
}
/*
* Using the established relp connection commit the messages.
*/
async function commit(msg){
return new Promise(async(resolve, reject) => {
let relpBatch = new RelpBatch();
relpBatch.insert(msg);

let resWindow = await relpConnection.commit(relpBatch);
console.log('After Batch-1 Completion....', resWindow)

let notSent = (resWindow === true) ? true : false; //Test purpose
while(notSent){
let res = await relpBatch.verifyTransactionAllPromise();
if(res){
notSent = false;
console.log('VerifyTransactionAllPromise......', res);
resolve(true);
}
else{
reject(false);
}
}
return resolve(true);
})
}
----

== TODO

* Handling Socket timeout
* Error Management

== Contributing

// Change the repository name in the issues link to match with your project's name

You can involve yourself with our project by https://github.com/teragrep/rlp_02/issues/new/choose[opening an issue] or submitting a pull request.

Contribution requirements:

. *All changes must be accompanied by a new or changed test.* If you think testing is not required in your pull request, include a sufficient explanation as why you think so.
. Security checks must pass
. Pull requests must align with the principles and http://www.extremeprogramming.org/values.html[values] of extreme programming.
. Pull requests must follow the principles of Object Thinking and Elegant Objects (EO).

Read more in our https://github.com/teragrep/teragrep/blob/main/contributing.adoc[Contributing Guideline].

=== Contributor License Agreement

Contributors must sign https://github.com/teragrep/teragrep/blob/main/cla.adoc[Teragrep Contributor License Agreement] before a pull request is accepted to organization's repositories.

You need to submit the CLA only once. After submitting the CLA you can contribute to all Teragrep's repositories.