googleapis / googleapis/google-cloud-node

Feature Proposal: Formal way to disable automatic diagnostic/instrumentation log entries

Open
#7,560 0 comments 0 reactions 1 assignee Claimed by @yoshi-approver View on GitHub
api: logging priority: p3 type: feature request
Dominant language
TypeScript
Stars
3.2k
Forks
712
Avg merge
2d 3h
Merged PRs (30d)
99

Description

The library currently automatically injects an "instrumentation" log entry (containing version and runtime info) upon the first log write in a process. While the library attempts to ensure this happens only once per process lifecycle, this behavior is problematic in several modern use cases:

1. **Ephemeral Environments:** In Serverless functions (FaaS), CLI tools, or rapid `child_process` executions, the "once per lifecycle" rationale breaks down, resulting in a significant percentage of "noise" logs that the developer did not request and cannot easily suppress.
2. **Log Volume/Cost:** For users with high-frequency, short-lived processes, these mandatory entries contribute to unnecessary ingestion costs and log clutter.
3. **Library Isolation:** Modern library design favors deterministic behavior without side-effects. Emitting log entries implicitly at the transport layer makes the library harder to embed safely in other tools.
4. **Limited User Benefit:** These entries consume user log quota and clutter streams while providing limited or no actionable value to application developers, who already know their runtime and library versions.
5. **Element of surprise:** A logging client emitting entries the user did not explicitly request violates the principle of least surprise.

## Current Workaround

Users can currently suppress this by setting:
```javascript
global.shouldSkipInstrumentationCheck = true
```
before the first log write, but this is undocumented and relies on internal implementation details.

## Technical Concerns in current implementation (`src/utils/instrumentation.ts`)

Beyond the lack of an opt-out, the current implementation has several architectural issues:

1. **In-place Data Mutation:** In `populateInstrumentationInfo`, the library mutates the user's `entryItem.data` object in-place (Lines [74-75](https://github.com/googleapis/nodejs-logging/blob/9cfdde70b9d79d9b76d5bc97d34a6ca10fbf07da/src/utils/instrumentation.ts#L74-L75)). This can lead to unexpected side-effects if the caller re-uses data objects.
2. **Global State Pollution:** The use of `global.instrumentationAdded` and `global.shouldSkipInstrumentationCheck` may conflict with other libraries and user code.
3. **Performance Overhead:** On the first write, the library performs an O(N) scan of all entries in a batch to look for existing instrumentation metadata, even if the user has no intention of providing it.
4. **Library Misidentification:** If a third-party library uses this package, its name is forcibly overwritten to "nodejs" unless it follows a specific prefixing convention (Lines [108-110](https://github.com/googleapis/nodejs-logging/blob/9cfdde70b9d79d9b76d5bc97d34a6ca10fbf07da/src/utils/instrumentation.ts#L108-L110)).
5. **Runtime Identification:** In environments like Bun, Deno or edge runtimes, reporting as "nodejs" without reporting the actual runtime is misleading.

## Proposed Solution

1. Add `disableInstrumentationLogging` to the `LoggingOptions` interface to allow the callers to skip instrumentation logging.
2. Instead of generic `shouldSkipInstrumentationCheck` and `instrumentationAdded` in the global object, use a singleton class addressed via `global[Symbol.for('google-cloud-logging-instrumentation')]` exposing getters/setters for the internal state.
3. Maintain backward compatibility by typeguarding `typeof global.shouldSkipInstrumentationCheck === 'boolean'` and `typeof global.instrumentationAdded === 'boolean'` during singleton initialization.
4. Avoid scanning or mutating user log entries. Instrumentation should be logged deterministically (once per process) - consistent with the [Go client implementation](https://github.com/googleapis/google-cloud-go/tree/main/logging), only when `loggingOptions.disableInstrumentationLogging` is not `true`.
5. Document the default instrumentation behavior and the opt-out mechanism in the README.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.