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);
}
}
},
},
});
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
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",
},
});