Activity Feeds V3 is in closed alpha — do not use it in production (just yet).

Logging

Overview

The SDK uses pre-scoped logging mechanism for you to use. Each scope represents a specific module (or a group of modules) that produce logs. The scopes the SDK operates on are as follows:

  • api-client - SDK API HTTP requests
  • token-manager - token management mechanism (link between token provider & ApiClient)
  • stable-ws-connection - WS connection and communication (messages) information
  • event-dispatcher - WS message/handler binding mechanism (exceptions from handlers that throw are not bubbled, only logged)

You can set up a sink and a log level for each of these scopes individually. The mechanism will use default scope if logger cannot find settings for the accessed scope. A “sink” is a function which gets funneled logs an SDK code produces. A sink gets a log level, message and other values we pass down to it as arguments from the SDK.

Log levels are pre-defined and are ordered by severity as such:

  • trace: 0
  • debug: 1
  • info: 2
  • warn: 3
  • error: 4

For example; if you set a log level to a value warn for a scope event-dispatcher, you will only see errors and warnings generated by the SDK for that specific scope.

Note that our SDK only logs errors that do not get re-thrown. Using our API (producing HTTP request) might result in errors which should be handled within individual integrations.

Usage

import { configureLoggers } from "@stream-io/feeds-client";
// or
import { configureLoggers } from "@stream-io/feeds-react-sdk";
// or
import { configureLoggers } from "@stream-io/feeds-react-native-sdk";

// arbitrary logging mechanism of your choice
import SuperLogger from "./SuperLogger";

configureLoggers({
  "api-client": {
    level: "error",
  },
  "event-dispatcher": {
    level: "warn",
    sink: (logLevel, message, ...rest) => {
      switch (logLevel) {
        case "warn": {
          console.warn(message, ...rest);
          break;
        }
        case "error": {
          SuperLogger.error(message, ...rest);
        }
      }
    },
  },
});

Note that you can instantiate StreamFeedsClient with configure_loggers_options which get passed to configureLoggers function during instantiation. Calling configureLoggers right after the instantiation (with different options) overrides the options passed to the client.

You can augment the settings of the default scope if you don’t want to apply custom sinks/levels to all the SDK-defined scopes individually.

import { configureLoggers } from "@stream-io/feeds-client";
// or
import { configureLoggers } from "@stream-io/feeds-react-sdk";
// or
import { configureLoggers } from "@stream-io/feeds-react-native-sdk";

import SuperLogger from "./SuperLogger";

configureLoggers({
  default: {
    level: "info",
    sink: (logLevel, message, ...rest) => {
      SuperLogger[logLevel](message, ...rest);
    },
  },
});

If you need to reset specific scopes during your application runtime to use defaults instead you can do so as follows:

import { configureLoggers } from "@stream-io/feeds-client";
// or
import { configureLoggers } from "@stream-io/feeds-react-sdk";
// or
import { configureLoggers } from "@stream-io/feeds-react-native-sdk";

configureLoggers({
  "event-dispatcher": {
    level: null,
    sink: null,
  },
});

This action will only reset the event-dispatcher scope and api-client scope will stay intact (considering previous examples). If you need to reset the defaults completely, you can do so as follows:

import { restoreDefaults } from "@stream-io/feeds-client";
// or
import { restoreDefaults } from "@stream-io/feeds-react-sdk";
// or
import { restoreDefaults } from "@stream-io/feeds-react-native-sdk";

restoreDefaults();

This action will clear all the pre-defined settings and restore default scope if it has been augmented.

Sentry Integration

Here is an example showing a basic Sentry integration:

import { LogLevel, configureLoggers, Sink } from "@stream-io/feeds-client";
// or
import { LogLevel, configureLoggers, Sink } from "@stream-io/feeds-react-sdk";
// or
import {
  LogLevel,
  configureLoggers,
  Sink,
} from "@stream-io/feeds-react-native-sdk";

import * as Sentry from "@sentry/nextjs";

const sentrySeverityByLogLevel: Record<LogLevel, Sentry.SeverityLevel> = {
  debug: "debug",
  info: "info",
  warn: "warning",
  error: "error",
};

const customSentrySink: Sink = (logLevel, message, ...rest) => {
  Sentry.captureEvent({
    level: sentrySeverityByLogLevel[logLevel],
    extra: args,
  });
};

configureLoggers({
  default: {
    sink: customSentrySink,
    level: "warn",
  },
});

© Getstream.io, Inc. All Rights Reserved.