react-native-logs

repository·master·Indexed 20 days ago

https://github.com/mowispace/react-native-logs

A performance-aware logging library for React Native, Expo, and react-native-web. It features custom severity levels, namespaces (extensions), and multiple transports including console, file writing (via react-native-fs or expo-file-system), Sentry, and Firebase Crashlytics. Version 5.6.0.

Tokens
8.8K
Snippets
29
Records
36
Agent score
63%

What's inside react-native-logs

  1. How namespaced loggers (Extensions) work

    master

    You can enable logging for specific parts of your application by creating namespaced loggers using the .extend(name) method. Extensions are controlled via the enabledExtensions array in the logger configuration. If an extension is not enabled, calls to that extended logger will be ignored.

    import { logger, consoleTransport } from "react-native-logs";
    
    var log = logger.createLogger({
      transport: consoleTransport,
      enabledExtensions: ["ROOT", "HOME"],
    });
    
    var rootLog = log.extend("ROOT");
    var homeLog = log.extend("HOME");
    var profileLog = log.extend("PROFILE");
    
    log.debug("print this"); // prints: <time> | DEBUG | print this
    rootLog.debug("print this"); // prints: <time> | ROOT | DEBUG | print this
    homeLog.debug("print this"); // prints: <time> | HOME | DEBUG | print this
    profileLog.debug("not print this"); // does nothing (extension not enabled)
  2. Improve logging performance with async mode

    master

    In React Native, you can prevent logging from impacting UI performance by setting async: true in your logger configuration.

    When async is enabled, the logger uses requestIdleCallback (in modern React Native/Hermes environments) or falls back to setTimeout to defer logging until the UI thread is idle. This prevents frame drops during animations or heavy rendering.

    const config = {
      async: true,
      // ... other config
    };
    
    const log = logger.createLogger(config);
  3. Configure logs for development vs production

    master

    In React Native, you can use the __DEV__ global variable to switch between different transports and severity levels. This ensures high-performance logging in production (e.g., saving to a file) while providing detailed console output during development.

    import {
      logger,
      consoleTransport,
      fileAsyncTransport,
    } from "react-native-logs";
    import RNFS from "react-native-fs";
    
    const config = {
      transport: __DEV__ ? consoleTransport : fileAsyncTransport,
      severity: __DEV__ ? "debug" : "error",
      transportOptions: {
        FS: RNFS,
      },
    };
    
    var log = logger.createLogger(config);
  4. Quick Start with react-native-logs

    master

    To get started, import logger and call createLogger(). By default, this creates a simple console logger with debug, info, warn, and error levels.

    import { logger } from "react-native-logs";
    
    var log = logger.createLogger();
    
    log.debug("This is a Debug log");
    log.info("This is an Info log");
    log.warn("This is a Warning log");
    log.error("This is an Error log");
  5. Implement a global logger pattern

    master

    To use a single logger instance throughout your React Native app, create a dedicated configuration file (e.g., config.js) to initialize the logger and export it. You can then import this instance into any file.

    For specific module-level logging, use .extend("NAME") on the exported global logger to create specialized extensions.

    // config.js
    import { logger, consoleTransport, fileAsyncTransport } from "react-native-logs";
    import RNFS from "react-native-fs";
    
    export const LOG = logger.createLogger({
      transport: __DEV__ ? consoleTransport : fileAsyncTransport,
      severity: __DEV__ ? "debug" : "error",
      transportOptions: {
        colors: {
          info: "blueBright",
          warn: "yellowBright",
          error: "redBright",
        },
        FS: RNFS,
      },
    });
    
    // app.js or other files
    import { LOG } from "./config";
    LOG.info("app log test");
    
    // module.js
    import { LOG } from "./config";
    const log = LOG.extend("HOME");
    log.info("home log test");
  6. Configure the logger via createLogger

    master

    Customize the logger by passing a configuration object to createLogger(). All parameters are optional and have default values.

    Configuration Options

    ParameterTypeDescriptionDefault
    severitystringMinimum severity level to display (least important level you want to see)debug
    transportfunction or [function]The transport function(s) for logsconsoleTransport
    transportOptionsObjectCustom options passed to the transportnull
    levelsObjectCustom log levels: {name: power}false
    asyncbooleanEnable async logs to improve app performancefalse
    asyncFuncfunctionCustom async function (cb: Function) => {return cb()}requestIdleCallback / setTimeout
    stringifyFuncfunctionCustom stringify function (msg: any) => stringcustomized JSON.stringify
    formatFuncfunctionCustom format function (level: string, extension?: string, msg: any) => stringdefault string format
    dateFormatstring or functiontime, local, utc, iso or (date: Date) => stringtime
    printLevelbooleanWhether to print the log leveltrue
    printDatebooleanWhether to print the log date/timetrue
    printFileLinebooleanWhether to print file name and line number (requires babel plugin)false
    fileLineOffsetnumberAdjust the line number offset0
    fixedExtLvlLengthbooleanEnsure consistent character count alignment for extensions and levelsfalse
    enabledbooleanEnable or disable loggingtrue
    enabledExtensionsstring[]Enable only certain namespacesnull
    import { logger, consoleTransport } from "react-native-logs";
    
    var log = logger.createLogger({
      levels: {
        debug: 0,
        info: 1,
        warn: 2,
        error: 3,
      },
      severity: "debug",
      transport: consoleTransport,
      transportOptions: {
        colors: {
          info: "blueBright",
          warn: "yellowBright",
          error: "redBright",
        },
      },
      async: true,
      dateFormat: "time",
      printLevel: true,
      printDate: true,
      fixedExtLvlLength: false,
      enabled: true,
    });
    
    log.debug("Debug message");
    log.info({ message: "hi!" });
  7. Configure logger transports and options

    master

    Transports are responsible for the final destination of your logs. You can provide a single transport function or an array of transport functions to broadcast logs to multiple destinations simultaneously.

    Available preset transports include:

    • consoleTransport: Standard console output.
    • mapConsoleTransport: A transport that maps logs to specific console methods.
    • fileAsyncTransport: Writes logs to a file asynchronously.
    • sentryTransport: Sends logs to Sentry.
    • crashlyticsTransport: Sends logs to Firebase Crashlytics.

    When using multiple transports, ensure transportOptions matches the requirements of the union of all provided transports.

  8. Use multiple transports simultaneously

    master

    You can pass an array of transports to the transport option in the logger configuration. This allows a single log message to be sent to multiple destinations (e.g., the console, a local file, Sentry, and Crashlytics) at once.

    Ensure that transportOptions contains all necessary dependencies for every transport in the array.

    import {
      logger,
      consoleTransport,
      fileAsyncTransport,
      sentryTransport,
      crashlyticsTransport,
      transportFunctionType,
    } from "react-native-logs";
    import RNFS from "react-native-fs";
    import * as Sentry from "@sentry/react-native";
    import crashlytics from "@react-native-firebase/crashlytics";
    
    const crashlyticsModule = crashlytics();
    
    // A custom transport function
    const customTransport: transportFunctionType = (props) => {
      console.log(props.level.text, props.msg);
    };
    
    const log = logger.createLogger({
      transport: [
        consoleTransport,
        fileAsyncTransport,
        sentryTransport,
        crashlyticsTransport,
        customTransport,
      ],
      transportOptions: {
        FS: RNFS,
        SENTRY: Sentry,
        CRASHLYTICS: crashlyticsModule,
        colors: {
          info: "blueBright",
          warn: "yellowBright",
          error: "redBright",
        },
      },
    });
  9. Use fileAsyncTransport to save logs to a file

    master

    The fileAsyncTransport saves logs to a text file. It requires a filesystem instance from either react-native-fs or expo-file-system. You can use the {date-today} placeholder in the fileName to create a new file daily (e.g., app_logs_{date-today}.log).

    import { logger, fileAsyncTransport } from "react-native-logs";
    import RNFS from "react-native-fs";
    
    var log = logger.createLogger({
      severity: "debug",
      transport: fileAsyncTransport,
      transportOptions: {
        FS: RNFS,
        fileName: `logs_{date-today}`, // Create a new file every day
      },
    });
    
    log.info("Print this string to a file");
  10. Use consoleTransport for formatted console output

    master

    The consoleTransport prints logs using console.log. You can customize the colors for different log levels and the colors for extension labels (namespaces) using ANSI color names. You can also provide a custom console object via consoleFunc.

    import { logger, consoleTransport } from "react-native-logs";
    
    var log = logger.createLogger({
      levels: {
        debug: 0,
        info: 1,
        warn: 2,
        error: 3,
      },
      transport: consoleTransport,
      transportOptions: {
        colors: {
          info: "blueBright",
          warn: "yellowBright",
          error: "redBright",
        },
        extensionColors: {
          root: "magenta",
          home: "green",
        },
      },
    });
    
    var rootLog = log.extend("root");
    var homeLog = log.extend("home");
    
    rootLog.info("Magenta Extension and bright blue message");
    homeLog.error("Green Extension and bright red message");