---
source_url: https://www.pubnub.com/docs/sdks/javascript/logging
title: Logging for JavaScript SDK
updated_at: 2026-06-19T11:37:36.288Z
sdk_name: PubNub JavaScript SDK
sdk_version: 11.0.2
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# Logging for JavaScript SDK

PubNub JavaScript SDK, use the latest version: 11.0.2

Install:

```bash
npm install pubnub@11.0.2
```

This page explains how to configure logging in the PubNub JavaScript Software Development Kit (SDK) using log levels and custom loggers.

## Logging architecture

The JavaScript SDK provides a flexible logging system. You can configure the logging system for different environments and use cases:

* Log levels control logging verbosity from detailed trace logs to errors only
* Built-in console logger automatically outputs to the browser console or Node.js console
* Custom loggers allow you to add custom logger implementations via the `loggers` configuration parameter
* Structured logging includes instance IDs, timestamps, log levels, and typed content

The SDK sends all log entries to both the built-in console logger and any configured custom loggers simultaneously.

## Log levels

The SDK uses six log levels. The levels range from most verbose to least verbose:

| Level | Purpose |
| --- | --- |
| `LogLevel.Trace` | Logs every detail including function calls, full payloads, internal variables, and state-machine transitions |
| `LogLevel.Debug` | Logs SDK logic including inputs and outputs to public methods, HTTP (Hypertext Transfer Protocol) requests and responses, and configuration properties |
| `LogLevel.Info` | Logs significant events such as successful initialization and connection status changes |
| `LogLevel.Warn` | Logs non-fatal events including deprecation warnings, request retries, and unusual conditions |
| `LogLevel.Error` | Logs errors, exceptions with stack traces, and HTTP failures |
| `LogLevel.None` | Disables logging (default) |

## Enable logging

Set the `logLevel` parameter during SDK initialization to enable console logging:

```javascript
import PubNub from 'pubnub';

// Initialize PubNub with debug-level logging
const pubnub = new PubNub({
  subscribeKey: 'mySubscribeKey',
  publishKey: 'myPublishKey',
  userId: 'myUniqueUserId',
  logLevel: PubNub.LogLevel.Debug
});
```

:::note Required User ID
Always set the `userId` to uniquely identify the user or device that connects to PubNub. This `userId` should be persisted and should remain unchanged for the lifetime of the user or the device. If you don't set the `userId`, you won't be able to connect to PubNub.
:::

### Configure detailed network logging

Use `LogLevel.Trace` to log detailed network information. This log level includes full HTTP request and response bodies:

```javascript
const pubnub = new PubNub({
  subscribeKey: 'mySubscribeKey',
  publishKey: 'myPublishKey',
  userId: 'myUniqueUserId',
  logLevel: PubNub.LogLevel.Trace
});
```

:::note Contact support
When troubleshooting issues, set `logLevel` to `LogLevel.Debug` or `LogLevel.Trace`. Reproduce the issue, copy the console output, and submit the output to [support@pubnub.com](https://www.pubnub.com/docs/mailto:support@pubnub.com).
:::

## Custom loggers

Implement the `Logger` interface to route logs to external monitoring services, databases, or analytics platforms. Custom loggers work alongside the built-in console logger.

### Logger interface structure

The `Logger` interface provides methods for all log levels:

```javascript
/**
 * Custom logger interface
 */
interface Logger {
  /**
   * Process a trace-level message
   * @param message - Structured log message
   */
  trace(message: LogMessage): void;

  /**
   * Process a debug-level message
   * @param message - Structured log message
   */
  debug(message: LogMessage): void;

  /**
   * Process an info-level message
   * @param message - Structured log message
   */
  info(message: LogMessage): void;

  /**
   * Process a warn-level message
   * @param message - Structured log message
   */
  warn(message: LogMessage): void;

  /**
   * Process an error-level message
   * @param message - Structured log message
   */
  error(message: LogMessage): void;
}
```

The SDK calls only the methods that correspond to the configured log level and above. For example, if you set `logLevel` to `LogLevel.Warn`, the SDK calls only the `warn()` and `error()` methods.

### Structured logging with LogMessage

Each `LogMessage` object provides structured information. The following table describes the common fields present in all log messages (the `BaseLogMessage` interface):

| Field | Description |
| --- | --- |
| `timestamp` | JavaScript Date object representing when the log was created |
| `pubNubId` | PubNub instance identifier (hash of instance ID) |
| `level` | Log level as a `LogLevel` enum value |
| `minimumLevel` | Minimum configured log level (useful for conditional detailed logging) |
| `location` | Source class or method that generated the log (when available) |
| `messageType` | Type of message content: `'text'`, `'object'`, `'error'`, `'network-request'`, or `'network-response'` |
| `message` | Actual log content (type depends on `messageType`) |

### Custom logger example

The following example shows a custom logger that sends errors and failed requests to a monitoring service. When using TypeScript, type narrowing enables IDE autocomplete for type-specific fields:

```typescript
import { Logger, LogMessage } from 'pubnub'

class MonitoringLogger implements Logger {
  /**
   * Process error-level messages
   */
  error(logMessage: LogMessage) {
    const { timestamp, pubNubId, location, messageType } = logMessage;
    
    if (messageType === 'error') {
      // TypeScript narrows type to ErrorLogMessage
      // IDE provides autocomplete for PubNubError fields
      monitoringService.reportError({
        message: logMessage.message.message,
        name: logMessage.message.name,
        stack: logMessage.message.stack,
        category: logMessage.message.status?.category,
        operation: logMessage.message.status?.operation,
        instanceId: pubNubId,
        timestamp: timestamp.toISOString(),
        location
      });
    } else if (messageType === 'network-request') {
      // TypeScript narrows type to NetworkRequestLogMessage
      // IDE provides autocomplete for canceled, failed, and details fields
      if (logMessage.canceled || logMessage.failed) {
        const url = `${logMessage.message.origin}${logMessage.message.path}`;
        
        monitoringService.reportNetworkFailure({
          url: url,
          method: logMessage.message.method,
          reason: logMessage.details,
          instanceId: pubNubId,
          timestamp: timestamp.toISOString()
        });
      }
    }
  }
  
  /**
   * Process warning messages
   */
  warn(logMessage: LogMessage) {
    if (logMessage.messageType === 'text') {
      // TypeScript narrows type to TextLogMessage
      // IDE provides autocomplete for string methods on message
      if (logMessage.message.includes('deprecated')) {
        analyticsService.trackDeprecation({
          warning: logMessage.message,
          instanceId: logMessage.pubNubId,
          timestamp: logMessage.timestamp.toISOString()
        });
      }
    }
  }
  
  /**
   * Process debug messages for configuration tracking
   */
  debug(logMessage: LogMessage) {
    if (logMessage.messageType === 'object') {
      // TypeScript narrows type to ObjectLogMessage
      // IDE provides autocomplete for details and ignoredKeys fields
      if (logMessage.details?.includes('configuration')) {
        analyticsService.trackConfigChange({
          config: logMessage.message,
          instanceId: logMessage.pubNubId,
          timestamp: logMessage.timestamp.toISOString()
        });
      }
    }
  }
  
  // No-op implementations for other levels if not needed
  trace() {}
  info() {}
}

// Configure SDK with custom logger
const pubnub = new PubNub({
  subscribeKey: 'mySubscribeKey',
  publishKey: 'myPublishKey',
  userId: 'myUniqueUserId',
  logLevel: PubNub.LogLevel.Debug,
  loggers: [new MonitoringLogger()]
});
```

### Multiple custom loggers

You can add multiple custom loggers for different purposes:

```javascript
const pubnub = new PubNub({
  subscribeKey: 'mySubscribeKey',
  publishKey: 'myPublishKey',
  userId: 'myUniqueUserId',
  logLevel: PubNub.LogLevel.Debug,
  loggers: [
    new MonitoringLogger(),  // Send errors to monitoring service
    new AnalyticsLogger(),   // Track usage patterns
    new FileLogger()         // Write detailed logs to file (Node.js)
  ]
});
```

## Log message types

The SDK generates five types of log messages. Each type has a corresponding TypeScript interface with specific fields.

### Text messages (TextLogMessage)

Text messages provide simple text for general logging. The `message` field contains a string:

```javascript
{
  timestamp: Date,
  pubNubId: 'pn-abc123',
  level: LogLevel.Info,
  minimumLevel: LogLevel.Debug,
  location: 'PubNub',
  messageType: 'text',
  message: 'PubNub client initialized successfully'
}
```

### Object messages (ObjectLogMessage)

Object messages provide structured objects such as configuration or internal state. The `message` field contains an object, array, or other value. Optional `details` and `ignoredKeys` fields provide additional context:

```javascript
{
  timestamp: Date,
  pubNubId: 'pn-abc123',
  level: LogLevel.Debug,
  minimumLevel: LogLevel.Debug,
  location: 'Configuration',
  messageType: 'object',
  message: { subscribeKey: 'sub-c-...', ssl: true, ... },
  details: 'Client configuration:'
}
```

### Error messages (ErrorLogMessage)

Error messages provide exception and error information. The `message` field contains a `PubNubError` object with error details and optional status information:

```javascript
{
  timestamp: Date,
  pubNubId: 'pn-abc123',
  level: LogLevel.Error,
  minimumLevel: LogLevel.Debug,
  location: 'PublishRequest',
  messageType: 'error',
  message: {
    name: 'PubNubError',
    message: 'Publish failed',
    stack: '...',
    status: { category: 'PNNetworkIssuesCategory', ... }
  }
}
```

### Network request messages (NetworkRequestLogMessage)

Network request messages provide HTTP request details. The `message` field contains a `TransportRequest` object. Optional `details`, `canceled`, and `failed` fields provide additional context about the request status:

```javascript
{
  timestamp: Date,
  pubNubId: 'pn-abc123',
  level: LogLevel.Debug,
  minimumLevel: LogLevel.Debug,
  location: 'PublishRequest',
  messageType: 'network-request',
  message: {
    method: 'POST',
    origin: 'https://ps.pndsn.com',
    path: '/publish/...',
    headers: { 'Content-Type': 'application/json' },
    body: '{"message":"Hello"}',
    queryParameters: { uuid: 'myUserId' }
  },
  canceled: false,
  failed: false
}
```

### Network response messages (NetworkResponseLogMessage)

Network response messages provide HTTP response details. The `message` field contains a `TransportResponse` object with status code, headers, and response body:

```javascript
{
  timestamp: Date,
  pubNubId: 'pn-abc123',
  level: LogLevel.Debug,
  minimumLevel: LogLevel.Debug,
  location: 'PublishRequest',
  messageType: 'network-response',
  message: {
    status: 200,
    url: 'https://ps.pndsn.com/publish/...',
    headers: { 'content-type': 'application/json' },
    body: '[1,"Sent","15234567890123456"]'
  }
}
```

## Logging in different environments

### Browser

The built-in console logger outputs to the browser JavaScript console:

```javascript
// Browser environment
const pubnub = new PubNub({
  subscribeKey: 'mySubscribeKey',
  publishKey: 'myPublishKey',
  userId: 'myUniqueUserId',
  logLevel: PubNub.LogLevel.Debug
});

// Logs appear in browser console (F12 Developer Tools)
```

### Node.js environment

The console logger outputs to the Node.js console:

```javascript
import PubNub from 'pubnub';

const pubnub = new PubNub({
  subscribeKey: 'mySubscribeKey',
  publishKey: 'myPublishKey',
  userId: 'myUniqueUserId',
  logLevel: PubNub.LogLevel.Debug
});

// Logs appear in terminal or console
```

### Node.js file logging

Implement a custom logger for Node.js file logging:

```javascript
import { Logger, LogLevel, LogMessage } from 'pubnub'
import * as fs from 'fs';
import path from 'path';

class FileLogger {
  constructor(private readonly logFilePath: string) {
    this.stream = fs.createWriteStream(logFilePath, { flags: 'a' });
  }
  
  log(logMessage: LogMessage) {
    const level = LogLevel[logMessage.level];
    const timestamp = logMessage.timestamp.toISOString();
    const location = logMessage.location || 'Unknown';
    const message = this.formatMessage(logMessage);
    
    this.stream.write(
      `${timestamp} [${level.toUpperCase()}] ${location}: ${message}\n`
    );
  }
  
  formatMessage(logMessage: LogMessage) {
    if (logMessage.messageType === 'text') {
      return logMessage.message;
    } else if (logMessage.messageType === 'object') {
      return `${logMessage.details || ''}\n${JSON.stringify(logMessage.message, null, 2)}`;
    } else if (logMessage.messageType === 'error') {
      return `${logMessage.message.name}: ${logMessage.message.message}`;
    }
    // Handle other message types
    return JSON.stringify(logMessage.message);
  }
  
  trace(logMessage) { this.log('trace', logMessage); }
  debug(logMessage) { this.log('debug', logMessage); }
  info(logMessage) { this.log('info', logMessage); }
  warn(logMessage) { this.log('warn', logMessage); }
  error(logMessage) { this.log('error', logMessage); }
}

// Use FileLogger with PubNub
const pubnub = new PubNub({
  subscribeKey: 'mySubscribeKey',
  publishKey: 'myPublishKey',
  userId: 'myUniqueUserId',
  logLevel: PubNub.LogLevel.Debug,
  loggers: [new FileLogger('./pubnub.log')]
});
```

##### Migrate from logVerbosity

The `logVerbosity` boolean parameter is deprecated. Use the `logLevel` parameter instead.

The following example shows the deprecated approach:

```javascript
// Deprecated approach
const pubnub = new PubNub({
  subscribeKey: 'mySubscribeKey',
  publishKey: 'myPublishKey',
  userId: 'myUniqueUserId',
  logVerbosity: true  // Deprecated
});
```

The following example shows the recommended approach:

```javascript
// Recommended approach
const pubnub = new PubNub({
  subscribeKey: 'mySubscribeKey',
  publishKey: 'myPublishKey',
  userId: 'myUniqueUserId',
  logLevel: PubNub.LogLevel.Debug
});
```

When you set `logVerbosity` to `true`, the SDK internally sets `logLevel` to `LogLevel.Debug` and emits a deprecation warning.

## Best practices

### Production environments

In production environments, use `LogLevel.Warn` or `LogLevel.Error`. These log levels minimize performance impact while capturing important issues.

### Development environments

During development, use `LogLevel.Debug` or `LogLevel.Trace`. These log levels provide detailed information for debugging.

### Custom logger performance

Implement custom loggers efficiently to avoid blocking the main thread. This consideration is especially important for network requests to external services.

### Protect sensitive data

Use the `ignoredKeys` field in object log messages to filter sensitive data. Filter data such as secret keys or user credentials.

### Implement log rotation

If you use file logging in Node.js, implement log rotation. Log rotation prevents unbounded log file growth.

### Use structured logging

Take advantage of structured `LogMessage` objects. Structured logging enables searchable and queryable logs in your monitoring systems.

For more information about configuration parameters, refer to [Configuration](https://www.pubnub.com/docs/sdks/javascript/api-reference/configuration#initialization).