You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

gcp-structured-logger

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gcp-structured-logger - npm Package Compare versions

Comparing version

to
1.4.5

src/request-properties.js

9

index.d.ts
/// <reference types="express-serve-static-core" />
/// <reference types="next" />
import { Request, RequestHandler, ErrorRequestHandler } from 'express-serve-static-core';

@@ -6,2 +7,3 @@ import { LogSeverity } from "./src/severity";

import { requestToHttpRequest } from "./src/request-transformers";
import { NextRequest as _NextRequest } from 'next/server'

@@ -47,3 +49,3 @@ /** @see https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#httprequest */

}
export type ExtractUser = (req: Request) => string | null | void;
export type ExtractUser = (req: Request | _NextRequest) => string | null | void;
export type Transport = (entry: TransportLogEntry, data: string | { message?: string, [k: string]: any }) => void;

@@ -76,2 +78,3 @@ export interface LoggingConfig {

makeErrorMiddleware(): ErrorRequestHandler;
nextJSMiddleware(req: _NextRequest): void;
/** @returns A function to call to detach from the process. */

@@ -88,4 +91,8 @@ attachToProcess(loggingTo: StructuredLogger): () => void;

}
declare interface NextRequest extends _NextRequest {
readonly log: StructuredRequestLogger;
}
}
export { requestToHttpRequest, LogSeverity };

@@ -21,3 +21,3 @@ const { finished } = require('stream')

* @private
* @param {import('express-serve-static-core').Request} req
* @param {import('./src/StructuredLogger').Request} req
*/

@@ -57,2 +57,9 @@ _makeRequestLog(req) {

/**
* @param {import('next/server').NextRequest} req
*/
nextJSMiddleware(req) {
Object.defineProperty(req, 'log', { value: this._makeRequestLog(req), enumerable: true, configurable: false })
}
/**
* @param {StructuredLogger} loggingTo

@@ -59,0 +66,0 @@ * @returns A function to call to detach from the process

3

package.json
{
"name": "gcp-structured-logger",
"version": "1.4.4",
"version": "1.4.5",
"description": "Structured logger for GCP logging",

@@ -43,4 +43,5 @@ "main": "index.js",

"mocha": "^10.2.0",
"next": "^12.3.4",
"sinon": "^15.0.3"
}
}
# GCP Structured Logger
[![Node.js CI](https://github.com/bookcreator/gcp-structured-logger/workflows/Node.js%20CI/badge.svg)](https://github.com/bookcreator/gcp-structured-logger/actions?query=workflow%3A%22Node.js+CI%22)
[![npm version](https://img.shields.io/npm/v/gcp-structured-logger.svg)](https://www.npmjs.org/package/gcp-structured-logger)

@@ -68,3 +69,3 @@ Outputs [structured logs](https://cloud.google.com/run/docs/logging#writing_structured_logs) that are formatted in GCP logging.

```js
const express = require('express') express()
const express = require('express')

@@ -91,2 +92,20 @@ const app = express()

## With NextJS
Can be use Next.js in the [middleware file](https://nextjs.org/docs/app/building-your-application/routing/middleware#convention), it should be added as the first middleware (to allow you to use `req.log` in future middlewares).
This then adds the `.log` property onto all requests.
```ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
logger.nextJSMiddleware(request);
// Continue or do usual middleware handling
return NextResponse.next();
}
```
You can also pass in a `requestUserExtractor` function when creating a `Logging` instance for setting the [user](https://cloud.google.com/error-reporting/reference/rest/v1beta1/ErrorContext#FIELDS.user) of the error.

@@ -93,0 +112,0 @@

@@ -0,5 +1,9 @@

const { getUrl, getHeader, getProtocol, getRemoteIp, getResponse } = require('./request-properties')
/** @typedef {import('./StructuredLogger').Request} Request */
/**
* Converts a request (and its attached response) to a `HttpRequest` for Stackdriver `LogEntry`.
*
* @param {import('express-serve-static-core').Request} req
* @param {Request} req
* @returns {import('../').LoggingHttpRequest}

@@ -9,3 +13,3 @@ */

// Copy from reporting
const { url, method, ...reportingReq } = requestToErrorReportingHttpRequest(req)
const { url, method, responseStatusCode, referrer, ...reportingReq } = requestToErrorReportingHttpRequest(req)
/** @type {import('../').LoggingHttpRequest} */

@@ -15,16 +19,19 @@ const httpReq = {

requestMethod: method,
...reportingReq,
}
if ('remoteIp' in reportingReq) httpReq.remoteIp = reportingReq.remoteIp
if ('referrer' in reportingReq) httpReq.referer = reportingReq.referrer
if ('userAgent' in reportingReq) httpReq.userAgent = reportingReq.userAgent
if ('responseStatusCode' in reportingReq) httpReq.status = reportingReq.responseStatusCode
if (referrer !== undefined) httpReq.referer = referrer
if (responseStatusCode !== undefined) httpReq.status = responseStatusCode
// Add in extra request info
const requestSize = req.get('content-length')
const protocol = getProtocol(req)
if (protocol !== undefined) httpReq.protocol = protocol
const requestSize = getHeader(req, 'content-length')
if (requestSize !== undefined) httpReq.requestSize = parseInt(requestSize)
if (req.protocol) httpReq.protocol = req.protocol + '/' + req.httpVersion
if (req.res) {
const res = getResponse(req)
if (res) {
// Response info
const responseSize = req.res.get('content-length')
const responseSize = res.get('content-length')
if (responseSize !== undefined) httpReq.responseSize = parseInt(responseSize)

@@ -47,3 +54,3 @@ }

*
* @param {import('express-serve-static-core').Request} req
* @param {Request} req
*/

@@ -53,23 +60,17 @@ function requestToErrorReportingHttpRequest(req) {

const httpReq = {
url: req.originalUrl,
url: getUrl(req),
method: req.method,
remoteIp: req.ip || (Array.isArray(req.ips) ? req.ips[0] : null)
}
if (!httpReq.remoteIp) {
const headerIps = req.get('x-forwarded-for')
if (headerIps && (!Array.isArray(headerIps) || headerIps.length > 0)) {
httpReq.remoteIp = Array.isArray(headerIps) ? headerIps[0] : headerIps
} else {
delete httpReq.remoteIp
}
}
const remoteIp = getRemoteIp(req)
if (remoteIp !== undefined) httpReq.remoteIp = remoteIp
const userAgent = req.get('user-agent')
const userAgent = getHeader(req, 'user-agent')
if (userAgent !== undefined) httpReq.userAgent = userAgent
const referrer = req.get('referrer')
const referrer = getHeader(req, 'referrer')
if (referrer !== undefined) httpReq.referrer = referrer
if (req.res) httpReq.responseStatusCode = req.res.statusCode
const res = getResponse(req)
if (res) httpReq.responseStatusCode = res.statusCode

@@ -76,0 +77,0 @@ return httpReq

@@ -35,2 +35,4 @@ const { format, formatWithOptions, inspect } = require('util')

/** @typedef {import('express-serve-static-core').Request | import('next/server').NextRequest} Request */
class StructuredLogger {

@@ -42,3 +44,3 @@

* @param {import('../').ServiceContext} serviceContext
* @param {?import('../').Transport} productionTransport
* @param {import('../').Transport?} productionTransport
* @param {{ [key: string]: string }} labels

@@ -71,4 +73,4 @@ */

* @protected
* @param {import('express-serve-static-core').Request} request
* @param {?import('../').ExtractUser} extractUser
* @param {Request} request
* @param {import('../').ExtractUser?} extractUser
*/

@@ -214,2 +216,10 @@ _requestChild(request, extractUser) {

/** @param {any[]} args */
trace(...args) {
const now = new Date()
const trace = { name: args.length === 0 ? 'Trace' : '' }
Error.captureStackTrace(trace, this.trace)
this._writeFormatted('DEFAULT', [...args, trace.stack], now)
}
/**

@@ -380,2 +390,3 @@ * @private

// @ts-expect-error: message not returned
const { message, ...messageData } = (() => {

@@ -484,4 +495,4 @@ if (typeof data === 'object' && data) {

* @param {{ [key: string]: string }} labels
* @param {import('express-serve-static-core').Request} request
* @param {?import('../').ExtractUser} extractUser
* @param {Request} request
* @param {import('../').ExtractUser?} extractUser
*/

@@ -488,0 +499,0 @@ constructor(projectId, logName, serviceContext, productionTransport, labels, request, extractUser) {

@@ -0,1 +1,3 @@

const { getHeader } = require('./request-properties')
/** Header that carries span context across Google infrastructure. */

@@ -7,19 +9,21 @@ const TRACE_CONTEXT_HEADER_NAME = 'x-cloud-trace-context'

* @param {string} projectId
* @param {import('express-serve-static-core').Request} req
* @param {import('./StructuredLogger').Request} req
* @returns {{} | { trace: string, spanId: string }}
*/
module.exports = function extractTraceContext(projectId, req) {
const traceContextHeader = req.get(TRACE_CONTEXT_HEADER_NAME)
const matches = TRACE_CONTEXT_HEADER_FORMAT.exec(traceContextHeader)
if (matches && matches.length === 4 && matches[0] === traceContextHeader) {
try {
return {
/** `projects/<PROJECT-ID>/traces/<TRACE-ID>` */
trace: `projects/${projectId}/traces/${matches[1]}`,
// Convert spanId to hex and ensure its always a length-16 hex string
spanId: BigInt(matches[2]).toString(16).padStart(16, '0'),
}
} /* c8 ignore next */ catch { /* Bad span number */ }
const traceContextHeader = getHeader(req, TRACE_CONTEXT_HEADER_NAME)
if (traceContextHeader !== null) {
const matches = TRACE_CONTEXT_HEADER_FORMAT.exec(traceContextHeader)
if (matches && matches.length === 4 && matches[0] === traceContextHeader) {
try {
return {
/** `projects/<PROJECT-ID>/traces/<TRACE-ID>` */
trace: `projects/${projectId}/traces/${matches[1]}`,
// Convert spanId to hex and ensure its always a length-16 hex string
spanId: BigInt(matches[2]).toString(16).padStart(16, '0'),
}
} /* c8 ignore next */ catch { /* Bad span number */ }
}
}
return {}
}