Redux Logging in Production with LogRocket

    Ben Edelstein
    Share

    Understanding problems in web apps is hard. Between mysterious JavaScript errors, user-reported bugs, and issues caught in QA, there’s a constant struggle to get ahead of the problems affecting your users. And these are just the obvious issues — most bugs are never actually reported since users who have a bad experience just leave or suffer in silence.

    Redux Logging with LogRocket

    To solve this problem, developers are increasingly adopting front-end logging tools, since modern state management libraries like Redux leave a rich audit trail. Logging actions and state in production makes it easy to understand bugs and user-reported issues.

    In this post, I’ll show you how to set up Redux logging with LogRocket. Then, I’ll discuss techniques for making Redux apps easier to debug.

    This post was originally published on logrocket.com and reposted here with the author’s permission. If you enjoy reading, why not check out some of Ben’s other articles? If you’d like to learn more about Redux, why not sign up for SitePoint Premium and enroll for our latest course: Forms with React and Redux?

    LogRocket: A DVR for Web Apps

    LogRocket dashboard

    LogRocket is a new type of developer tool. It’s like a DVR for web apps, recording literally everything that happens on your site. It works perfectly with any app, regardless of framework, and has plugins to log additional context from React, Redux, Vue.js, and Angular. With LogRocket, instead of guessing why problems happen, you can replay sessions with bugs or user issues to quickly understand the root cause.

    In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single page apps.

    Setting up LogRocket

    Setting up LogRocket is easy, and only requires adding a few lines of code to your app:

    1. Install with npm: npm i --save logrocket.
    2. Create a free account at https://app.logrocket.com, and take note of your application id.
    3. Initialize LogRocket in your app:
      import LogRocket from 'logrocket';
      // Initialize LogRocket with your app ID
      LogRocket.init(<your_application_id>);
      
    4. Add the Redux middleware.
      import { applyMiddleware, createStore } from 'redux';
      const store = createStore(
        reducer, // your app reducer
        applyMiddleware(middlewares, LogRocket.reduxMiddleware()),
      );
      

    That’s it for the basic setup- this is all you need to get started with LogRocket!

    LogRocket also has plugins for alternate Flux implementations like ngrx and vuex, which you can read about here.

    Replaying User Sessions

    LogRocket User Session

    Replaying a session in LogRocket is like seeing it happen in your own browser. You can inspect Redux actions with the full action payload as well as the previous and next states.

    LogRocket User Session

    LogRocket captures both network requests and responses and lets you dig in to specific requests and see the headers and body. The waterfall chart shows timings, making it easy to see which requests were slow, or if a potential race condition occurred.

    LogRocket Timeline

    Sometimes Redux logs alone aren’t enough to understand a bug, especially when dealing with user-reported issues. LogRocket’s video replay helps here by letting you see exactly what a user saw in your app.

    Since this video is actually a reconstruction of the DOM (and not a real video) you can inspect HTML/CSS to understand visual bugs, or play at 2x speed to gain a quick understanding of what a user did in the app when handling support issues.

    Integrating Redux Logging into Your Workflow

    Being able to replay user sessions and see Redux logs is helpful across the development workflow.

    Fixing Bugs

    LogRocket Bug

    LogRocket integrates with error reporting tools like Sentry and Bugsnag, letting you see Redux logs and video for every bug. This is not only helpful for fixing bugs, but also for understanding error impact, since some JavaScript errors are completely innocuous. By watching the video from when an error occurred, you can
    easily tell if it actually affects users, or can be ignored.

    Support

    All too often, users will report issues but not give enough context to figure out exactly what happened.

    If you are using a chat support tool like Intercom, you can integrate LogRocket directly so that it adds a note with a recording URL whenever a user starts chatting.

    LogRocket support

    If you are integrating with a more general analytics tool, you can add recording URL’s with a tracking API like this:

    LogRocket.getSessionURL(function (sessionURL) {
      analytics.track('LogRocket recording', sessionURL);
    })
    

    Making the Most of Production Redux Logging

    Production logging is immediately useful in all Redux apps, but by architecting your app with logging in mind, you can ensure that logs are maximally useful when debugging issues.

    Try to Keep Most State in Redux

    I don’t want to get into the debate on local vs Redux state here, but when deciding whether a given piece of state should be in Redux, ask yourself if seeing that state could be helpful when debugging issues. If the answer is yes, consider putting that state in Redux so that it will be logged with crash reports and user issues.

    Use Data Fetching Libraries That Leverage Redux

    Libraries like apollo-client for GraphQL, and redux-query for REST both facilitate fetching data from the network via Redux. They use Redux as a persistence layer, meaning that when debugging issues, you can inspect your Redux logs to see what data these clients have fetched.

    If you’d prefer a simpler approach, you can roll your own data fetching “framework” by simply dispatching explicit actions when querying and receiving data from the network.

    Use Redux to Handle Sources of Non-Determinism

    When accessing data from APIs like websockets, local storage, IndexedDB, or even Date(), consider dispatching Redux actions with the result, so that you can easily debug these in the future. For example, when listening on a websocket, dispatch a Redux action on every message- that way you can see the data in your
    Redux logs.

    Leverage Other Console APIs

    Console methods like console.time(), console.count() and console.group() let you add rich data to your logs like React component render counts, transaction timings and component lifecycle logs. If
    you’re interested in learning more, I wrote a post about this here.

    Build and Upload Source Maps to LogRocket

    LogRocket supports source maps which you can upload via a cli. By doing this you can see symbolicated stack traces for JavaScript errors, Redux actions, console logs and
    network requests, which lets you see where particular actions were triggered in your code.

    Conclusion

    React and Redux are often lauded as tools for building maintainable applications — a significant component of which is debuggability. Logging Redux data in production gives such insight since bugs and other user-reported issues can be easily debugged by inspecting Redux state, network requests and the DOM.

    Using LogRocket for Redux logging can greatly simplify fixing bugs and supporting your users. You can get started with LogRocket here.