Skip to content

Commit

Permalink
feat: updated sdk dependency to use v3 of aws-javascript
Browse files Browse the repository at this point in the history
  • Loading branch information
biggaji committed Nov 15, 2023
1 parent 8942f87 commit c6286f5
Show file tree
Hide file tree
Showing 13 changed files with 2,405 additions and 600 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,5 @@ dist

# TernJS port file
.tern-port

tests/**
8 changes: 8 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"tabWidth": 2,
"printWidth": 80,
"singleQuote": true,
"semi": true,
"trailingComma": "all",
"proseWrap": "always"
}
117 changes: 81 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,75 +1,120 @@
# send-cloudwatch-log
This sdk allows you to easily send logs from your nodeJs application to AWSCloudWatchLogs service, it is easy and simple to implement.

This sdk allows you to easily send logs from your Node.js application to
AWSCloudWatchLogs service. It is easy and very simple to use.

## Requirement

This sdk requires a node version 8, 10 or higher to work effectively.

## Installation
## Installation

```bash
npm install send-cloudwatch-log
or
yarn add send-cloudwatch-log
```
Using Npm?

## Usage
```sh
npm install --save send-cloudwatch-log
```

Using Yarn?

```js
const cwlogger = require("send-cloudwatch-log");
```sh
yarn add send-cloudwatch-log
```

//create an instance of the cwlogger , you can create as many instance as you want.
## Usage

// For each instance, you just need to pass your aws_credentials and provide the logGroupName and logStreamName. See the example below:
```js
const cwlogger = require('send-cloudwatch-log');

const logger = new cwlogger({
accessKeyId: "AWS_ACCESS_KEY_ID",
secretAccessKey: "AWS_SECRET_ACCESS_KEY",
region: "AWS_REGION",
// Create an instance of the cwlogger , you can create as many instance as you want.
// For each instance, you just need to pass the required configs details as seen in the example below:
const logger = new cwlogger(
{
accessKeyId: 'AWS_ACCESS_KEY_ID',
secretAccessKey: 'AWS_SECRET_ACCESS_KEY',
region: 'AWS_REGION',
},
{
logGroupName: "LOG_GROUP_NAME",
logStreamName: "LOG_STREAM_NAME",
logGroupName: 'LOG_GROUP_NAME',
logStreamName: 'LOG_STREAM_NAME',
},
);

/**
* Create a log object
* Each log object must contain only the 'message' and 'timestamp' properties.
* { message: string, timestamp: number}
* Since message must be a string, so you can also use the JSON.stringify() method to wrap objects as a string
* timestamp must be in milliseconds, so you can use either Date.now() or new Date().getTime();
*/

let log = {
message: 'Hello World from cwLogger',
timestamp: Date.now(),
};


// Send log to AWSCloudWatchLogs
// The sendLog() method accepts either a single log object or an array of log objects.

// Sending the a single log object
logger
.sendLog(log)
.then((resp) => {
// resp -> the response from AWSCloudWatchLogs
console.log(`Logs sent successfully`, resp);
})
.catch((err) => {
console.log(`An error occured`, err);
});

//create log a log
//Each log must be an object containing only message and timestamp e.g {message: "STRING", timestamp: number}.

//timestamp must be in milliseconds

let log = {
message: "Hello World from cwLogger",
timestamp: Date.now()
let logs = [
{
message: 'Hello World from cwLogger',
timestamp: Date.now(),
};
{
message: JSON.stringify({ error: 'TypeError', message: 'timestanps must be a number'}),
timestamp: Date.now(),
};
];

//send log to AWSCloudWatchLogs

logger.sendLog(log)
.then(resp => {
// Sending the an array | list of log object
logger
.sendLog(logs)
.then((resp) => {
// resp -> the response from AWSCloudWatchLogs
console.log(`Logs sent successfully`, resp);
})
.catch(err => {
.catch((err) => {
console.log(`An error occured`, err);
});



```

The `sendLog()` method takes the log as a parameter and sends it to the AWSCloudWatchLogs. It returns a promise which when successful, returns an object which contains a nextSequenceToken and a customised successful message `Logs sent successfully`, or an error with a message showing the reason it failed.
The `sendLog()` method takes the log object or an array of log objects as an
argument and sends it to the AWSCloudWatchLogs.

It returns a promise which when successful, returns an object which contains a
nextSequenceToken and $metadata from AWSCloudWatchLogs or an error with a
message showing the reason it failed.

![Image Screenshot of AwsCloudWatchLogs stream event](https://res.cloudinary.com/dahn8uiyc/image/upload/v1642677223/logger_baqit9.png)

## How can I thank you?

Why not star the github repo? I'd love the attention! Why not share the link for this repository on Twitter or HackerNews? Spread the word!
Why not star the Github repository? I'd love the attention!

Why not share the link for this repository on X or HackerNews?

Don't forget to [follow me on twitter](https://twitter.com/bigg_aji)!
Spread the word!

Don't forget to [follow me on X](https://x.com/oxwware)!

Thanks!

Tobiloba Ajibade.

## License

The MIT License [(MIT)]("https://mit-license.org/).
5 changes: 2 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const { SendCloudWatchLogs } = require('./lib/src/logger');

const { SendCloudWatchLogs } = require("./lib/src/logger")

module.exports = SendCloudWatchLogs;
module.exports = SendCloudWatchLogs;
11 changes: 11 additions & 0 deletions lib/src/@utils/validateRequiredKeys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateRequiredKeys = void 0;
function validateRequiredKeys(obj) {
for (let key in obj) {
if (obj[key] === undefined) {
throw new Error(`${key} is required to initialize the logger class instance`);
}
}
}
exports.validateRequiredKeys = validateRequiredKeys;
116 changes: 26 additions & 90 deletions lib/src/logger.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,8 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SendCloudWatchLogs = void 0;
const aws = __importStar(require("aws-sdk"));
const client_cloudwatch_logs_1 = require("@aws-sdk/client-cloudwatch-logs");
const validateRequiredKeys_1 = require("./@utils/validateRequiredKeys");
/**
* @class SendCloudWatchLogs
* @description Send logs to AWSCloudWatchLogs service
Expand All @@ -29,20 +11,25 @@ const aws = __importStar(require("aws-sdk"));
class SendCloudWatchLogs {
aws_cred;
logParams;
// CLoudWatchLog client instance
cwl;
constructor(aws_cred, logParams) {
// Validate Required fields
(0, validateRequiredKeys_1.validateRequiredKeys)(aws_cred);
(0, validateRequiredKeys_1.validateRequiredKeys)(logParams);
this.aws_cred = aws_cred;
this.logParams = logParams;
const { accessKeyId, region, secretAccessKey } = this.aws_cred;
// Initialize aws-sdk with credentials
const cwl = new aws.CloudWatchLogs({
apiVersion: "2014-03-28",
region: `${this.aws_cred.region}`,
const cwl = new client_cloudwatch_logs_1.CloudWatchLogsClient({
region,
credentials: {
accessKeyId: this.aws_cred.accessKeyId,
secretAccessKey: this.aws_cred.secretAccessKey,
accessKeyId,
secretAccessKey,
},
apiVersion: '2014-03-28',
});
// assign the cloudwatch log instance to the cwl property
// Assign the cloudwatch log client instance to the cwl property
this.cwl = cwl;
}
/**
Expand All @@ -52,72 +39,21 @@ class SendCloudWatchLogs {
* @returns { Object } - Success response object
*/
async sendLog(log) {
// get the sequence token
let NSTParams = {
logGroupName: this.logParams.logGroupName,
logStreamNamePrefix: this.logParams.logStreamName,
limit: 1,
orderBy: "LogStreamName",
descending: false,
};
// sendlogs params
let sendLogsParams = {};
let NStoken = await this.getLogNST(NSTParams);
// assign the sequence token
if (NStoken !== undefined) {
sendLogsParams.sequenceToken = NStoken;
try {
const { logGroupName, logStreamName } = this.logParams;
const logEvents = Array.isArray(log) ? log : [log];
const LogRequestParams = {
logGroupName,
logStreamName,
logEvents,
};
const command = new client_cloudwatch_logs_1.PutLogEventsCommand(LogRequestParams);
const response = await this.cwl.send(command);
return response;
}
else {
sendLogsParams.sequenceToken = undefined;
catch (error) {
throw error;
}
return new Promise((resolve, reject) => {
// assign more properties to the sendLogsParams Object
sendLogsParams.logGroupName = this.logParams.logGroupName;
sendLogsParams.logStreamName = this.logParams.logStreamName;
sendLogsParams.logEvents = [log];
this.cwl.putLogEvents(sendLogsParams, (err, data) => {
if (err) {
reject(err);
}
else {
let resp = {
data,
message: "Logs sent successfully",
sentAt: Date.now(),
};
resolve(resp);
}
});
});
}
/**
* @memberof CWLogger
* @type { method } getLogNST - get the next sequence token
* @param params getLogNSTParams - { log_group_name, limit, descending, orderBy }
* @returns { String } The next sequence token of the log stream
*/
async getLogNST(params) {
return new Promise((resolve, reject) => {
this.cwl.describeLogStreams(params, (err, logStream) => {
if (err) {
reject(err);
}
else {
if (logStream !== undefined) {
if (logStream.logStreams.length > 0) {
resolve(logStream.logStreams[0].uploadSequenceToken);
}
else {
resolve("No log stream found, failed to get sequence token");
}
}
else {
resolve("No log stream found");
}
}
});
});
}
}
exports.SendCloudWatchLogs = SendCloudWatchLogs;
;
2 changes: 2 additions & 0 deletions lib/types/loggerTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
Loading

0 comments on commit c6286f5

Please sign in to comment.