Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

cf-nodejs-logging-support

Package Overview
Dependencies
Maintainers
5
Versions
100
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cf-nodejs-logging-support - npm Package Compare versions

Comparing version 6.11.0 to 6.12.0

docs/general-usage/05-stacktraces.md

99

core/log-core.js

@@ -15,2 +15,4 @@ const util = require("util");

const MAX_STACKTRACE_SIZE = 55 * 1024;
const LOG_TYPE = "log";

@@ -94,7 +96,7 @@ const LOGGING_LEVELS = {

var boundServices = parseJSONSafe(process.env.VCAP_SERVICES);
if(boundServices["application-logs"]) {
if (boundServices["application-logs"]) {
cfCustomEnabled = true;
defaultCustomEnabled = false;
}
if(boundServices["cloud-logs"]) {
if (boundServices["cloud-logs"]) {
defaultCustomEnabled = true;

@@ -106,3 +108,3 @@ }

var tmp = {};
if(value)
if (value)
try {

@@ -138,3 +140,3 @@ tmp = JSON.parse(value);

if (!pass) {
continue;
continue;
}

@@ -288,5 +290,5 @@ }

var setRequestLogLevel = function(level) {
var setRequestLogLevel = function (level) {
levelInt = getLogLevelFromName(level);
if(levelInt != null) {
if (levelInt != null) {
requestLogLevel = level;

@@ -333,3 +335,3 @@ return true;

// due to different rollover times for process.hrtime and now.getTime
if(logObject.written_ts < lastTimestamp)
if (logObject.written_ts < lastTimestamp)
logObject.written_ts += NS_PER_MS;

@@ -461,7 +463,13 @@ lastTimestamp = logObject.written_ts;

var customFieldsFromArgs = {};
if (typeof args[args.length - 1] === "object") {
if (isValidObject(args[args.length - 1])) {
customFieldsFromArgs = args[args.length - 1];
var lastArg = args[args.length - 1];
if (typeof lastArg === "object") {
if (isErrorWithStacktrace(lastArg)) {
logObject.stacktrace = prepareStacktrace(lastArg.stack);
} else if (isValidObject(lastArg)) {
if (isErrorWithStacktrace(lastArg._error)) {
logObject.stacktrace = prepareStacktrace(lastArg._error.stack);
delete lastArg._error;
}
customFieldsFromArgs = lastArg;
}

@@ -567,3 +575,3 @@ args.pop();

var registerCustomFields = function (fieldNames) {
registeredCustomFields = [];

@@ -651,3 +659,3 @@

if(defaultCustomEnabled || logObject[key] != null || isSettable(key))
if (defaultCustomEnabled || logObject[key] != null || isSettable(key))
logObject[key] = value;

@@ -666,5 +674,5 @@

var key;
for(var i = 0; i < registeredCustomFields.length; i++) {
for (var i = 0; i < registeredCustomFields.length; i++) {
key = registeredCustomFields[i]
if(customFields[key])
if (customFields[key])
res.string.push({

@@ -676,3 +684,3 @@ "k": key,

}
if(res.string.length > 0)
if (res.string.length > 0)
logObject["#cf"] = res;

@@ -682,6 +690,6 @@ }

var isSettable = function(key) {
var isSettable = function (key) {
if (settableConfig.length == 0) return false;
for(var i = 0; i < settableConfig.length; i++) {
if(settableConfig[i] == key) return true;
for (var i = 0; i < settableConfig.length; i++) {
if (settableConfig[i] == key) return true;
}

@@ -789,2 +797,51 @@ return false;

// check if the given object is an Error with stacktrace using duck typing
var isErrorWithStacktrace = function (obj) {
if (obj && obj.stack && obj.message && typeof obj.stack === "string" && typeof obj.message === "string") {
return true;
}
return false;
}
// Split stacktrace into string array and truncate lines if required by size limitation
// Truncation strategy: Take one line from the top and two lines from the bottom of the stacktrace until limit is reached.
var prepareStacktrace = function (stacktraceStr) {
var fullStacktrace = stacktraceStr.split('\n');
var totalLineLength = fullStacktrace.reduce((acc, line) => acc + line.length, 0);
if (totalLineLength > MAX_STACKTRACE_SIZE) {
var truncatedStacktrace = [];
var stackA = [];
var stackB = [];
var indexA = 0;
var indexB = fullStacktrace.length - 1;
var currentLength = 73; // set to approx. character count for "truncated" and "omitted" labels
for (let i = 0; i < fullStacktrace.length; i++) {
if (i % 3 == 0) {
let line = fullStacktrace[indexA++];
if (currentLength + line.length > MAX_STACKTRACE_SIZE) {
break;
}
currentLength += line.length;
stackA.push(line);
} else {
let line = fullStacktrace[indexB--];
if (currentLength + line.length > MAX_STACKTRACE_SIZE) {
break;
}
currentLength += line.length;
stackB.push(line);
}
}
truncatedStacktrace.push("-------- STACK TRACE TRUNCATED --------");
truncatedStacktrace = [...truncatedStacktrace, ...stackA];
truncatedStacktrace.push(`-------- OMITTED ${fullStacktrace.length - (stackA.length + stackB.length)} LINES --------`);
truncatedStacktrace = [...truncatedStacktrace, ...stackB.reverse()];
return truncatedStacktrace;
}
return fullStacktrace;
}
// writes static field values to the given logObject

@@ -812,4 +869,4 @@ var writeStaticFields = function (logObject) {

//Sets the custom field format by hand. Returns true on correct strings.
var overrideCustomFieldFormat = function(value) {
if(typeof value == "string") {
var overrideCustomFieldFormat = function (value) {
if (typeof value == "string") {
switch (value) {

@@ -816,0 +873,0 @@ case "application-logging":

@@ -11,5 +11,5 @@ ---

{: .no_toc }
Sometimes it is useful to change the logging level threshold for a specific request.
This can be achieved using a special header field or setting directly within the corresponding request handler.
Changing the logging level threshold affects if logs with a specific level are written.
For debugging purposes it can be useful to change the logging level threshold for specific requests.
This can be achieved using a special header field or setting directly within the corresponding request handler.
Changing the logging level threshold affects if logs with a specific level are written.
It has no effect on the level reported as part of the logs.

@@ -27,18 +27,45 @@

## Change logging level threshold via header field
You can change the logging level threshold for a specific request by providing a JSON Web Token ([JWT](https://de.wikipedia.org/wiki/JSON_Web_Token)) via the request header.
Using this feature allows you to change the logging level threshold dynamically without the need to redeploy your app.
### 1 Creating a JWT
JWTs are signed claims, which consist of a header, a payload and a signature.
You can create JWTs by using the [TokenCreator](https://github.com/SAP/cf-nodejs-logging-support/tree/master/tools/token-creator) from the tools folder.
You can change the logging level threshold for a specific request by providing a JSON Web Token ([JWT](https://de.wikipedia.org/wiki/JSON_Web_Token)) via the request header.
Using this feature allows changing the logging level threshold dynamically without the need to redeploy your app.
Basically, JWTs are signed using RSA or HMAC signing algorithms.
But we decided to support RSA algorithms (RS256, RS384 and RS512) only.
### 1 Creating a key-pair
To sign and verify JWTs a PEM encoded private key and a matching public key is required.
You can create a key-pair using the following command:
```sh
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
```
The generated key-pair can be found in `private.pem` and `public.pem` files.
### 2 Creating a JWT
JWTs are signed claims, which consist of a header, a payload, and a signature.
They can be signed using RSA or HMAC signing algorithms.
For this use-case we decided to support RSA algorithms (RS256, RS384 and RS512) only.
In contrast to HMAC algorithms (HS256, HS384 and HS512), RSA algorithms are asymmetric and therefore require key pairs (public and private key).
The tool mentioned above takes a log level, creates a key pair and signs the resulting JWT with the private key.
The payload of a JWT looks like this:
You can create JWTs by using the provided [TokenCreator](https://github.com/SAP/cf-nodejs-logging-support/tree/master/tools/token-creator):
```sh
cd tools/token-creator/
npm install
node token-creator.js -f <path private.pem> -v <validity period> -i <issuer> <level>
```
The `<validity period>` sets the number of days the JWT will be valid.
Once the created JWT expired, it can no longer be used for setting logging level threshold.
Provide a numeric input for this placeholder.
Provide a valid e-mail address for the `<issuer>` parameter.
Specify one of the seven supported logging levels for the `<level>` argument: *off*, *error*, *warn*, *info*, *verbose*, *debug*, and *silly*.
The payload of the created JWT has the following structure:
```js
{
"issuer": "<valid e-mail address>",
"issuer": "<e-mail address>",
"level": "debug",

@@ -50,22 +77,32 @@ "iat": 1506016127,

This library supports seven logging levels: *off*, *error*, *warn*, *info*, *verbose*, *debug* and *silly*.
Make sure that your JWT specifies one of them in order to work correctly.
It is also important to make sure that the JWT has not been expired, when using it.
### 3 Providing the public key
### 2 Providing the public key
The logging library will verify JWTs attached to incoming requests.
In order to do so, the public key (from above) needs to be provided via an environment variable called *DYN_LOG_LEVEL_KEY*:
The logging library will verify JWTs attached to incoming requests.
In order to do so, the public key (from `public.pem` file) needs to be provided via an environment variable called DYN_LOG_LEVEL_KEY:
```text
DYN_LOG_LEVEL_KEY: <encoded public key>
```
DYN_LOG_LEVEL_KEY: <your public key>
Typically your public key file should have following structure:
```text
-----BEGIN PUBLIC KEY-----
<encoded public key>
-----END PUBLIC KEY-----
```
Redeploy your app after setting up the environment variable.
Instead of using the whole content of the `public.pem` file, you can also only provide the `<encoded key>` section to the environment variable.
### 3 Attaching JWTs to requests
Provide the created JWTs via a header field named 'SAP-LOG-LEVEL'. The logging level threshold will be set to the provided level for this request and corresponding custom log messages.
Redeploy your app after setting the environment variable.
Note: If the provided JWT cannot be verified, is expired or contains an invalid logging level, the library ignores it and uses the global logging level threshold.
### 4 Attaching JWTs to requests
Provide the created JWT via a header field named 'SAP-LOG-LEVEL'. The logging level threshold will be set to the provided level for this request and corresponding custom log messages.
**Note**: If the provided JWT cannot be verified, is expired, or contains an invalid logging level, the library ignores it and uses the global logging level threshold.
If you want to use another header name for the JWT, you can specify it using an environment variable:
```
```text
DYN_LOG_HEADER: MY-HEADER-FIELD

@@ -75,6 +112,9 @@ ```

## Change logging level threshold within request handlers
You can also change the logging level threshold for all requests of a specific request handler by calling:
```js
req.setLoggingLevel("verbose");
```
This feature is also available for [Child Loggers](/cf-nodejs-logging-support/advanced-usage/child-loggers#).

@@ -12,4 +12,4 @@ ---

In addition to request logging this library also supports logging of application messages.
Message logs contain at least some message and also CF metadata.
In addition to request logging this library also supports logging of application messages.
Message logs contain at least some message and also CF metadata.

@@ -26,2 +26,3 @@ <details open markdown="block">

## Logging levels
Following common logging levels are supported:

@@ -37,2 +38,3 @@

Set the minimum logging level for logs as follows:
```js

@@ -45,2 +47,3 @@ log.setLoggingLevel("info");

## Writing message logs
There are so called *convenience methods* available for all supported logging levels.

@@ -50,41 +53,46 @@ These can be called to log a message using the corresponding level.

You can find several usage examples below demonstrating options to be specified when calling a log method.
All methods get called on a `logger` object, which provides a so called *logging context*.
You can find several usage examples below demonstrating options to be specified when calling a log method.
All methods get called on a `logger` object, which provides a so called *logging context*.
You can find more information about logging contexts in the [Logging Contexts](/cf-nodejs-logging-support/general-usage/logging-contexts) chapter.
In the simplest case, `logger` is an instance of imported `log` module.
In the simplest case, `logger` is an instance of imported `log` module.
- Simple message
```js
logger.info("Hello World");
// ... "msg":"Hello World" ...
```
- Simple message:
- Message with additional numeric value
```js
logger.info("Listening on port %d", 5000);
// ... "msg":"Listening on port 5000" ...
```
```js
logger.info("Hello World");
// ... "msg":"Hello World" ...
```
- Message with additional string values
```js
logger.info("This %s a %s", "is", "test");
// ... "msg":"This is a test" ...
```
- Message with additional numeric value:
- Message with additional json object to be embedded in to the message
```js
logger.info("Test data %j", {"field" :"value"}, {});
// ... "msg":"Test data {\"field\": \"value\"}" ...
```
```js
logger.info("Listening on port %d", 5000);
// ... "msg":"Listening on port 5000" ...
```
In some cases you might want to set the actual logging level from a variable.
Instead of using conditional expressions you can simply use following method, which also supports format features described above.
```js
var level = "debug";
logger.logMessage(level, "Hello World");
// ... "msg":"Hello World" ...
```
- Message with additional string values:
```js
logger.info("This %s a %s", "is", "test");
// ... "msg":"This is a test" ...
```
- Message with additional json object to be embedded in to the message:
```js
logger.info("Test data %j", {"field" :"value"}, {});
// ... "msg":"Test data {\"field\": \"value\"}" ...
```
- In case you want to set the actual logging level from a variable, you can use following method, which also supports format features described above:
```js
var level = "debug";
logger.logMessage(level, "Hello World");
// ... "msg":"Hello World" ...
```
## Checking log severity levels
It can be useful to check if messages with a specific severity level would be logged.
It can be useful to check if messages with a specific severity level would be logged.
You can check if a logging level is active as follows:

@@ -100,4 +108,5 @@

There are convenience methods available for this feature:
```js
var isDebugActive = log.isDebug();
```
```
{
"name": "cf-nodejs-logging-support",
"version": "6.11.0",
"version": "6.12.0",
"description": "Logging tool for Cloud Foundry",

@@ -5,0 +5,0 @@ "keywords": [

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc