Reactotron transport for react-native-logs


TL;DR
The custom Reactotron transport for react-native-logs
improves logging by handling various message types, adding metadata, and allowing custom prefixes, making your logs more informative and easier to manage.
The Backstory
Logging is a crucial part of development, especially when debugging or monitoring application behavior. Reactotron is a popular tool for inspecting React and React Native apps, and integrating it with react-native-logs
can provide a more seamless logging experience. This custom transport enhances the default logging functionality by adding features like timestamps and custom prefixes.
The Problem
While react-native-logs
is powerful, it might not cover all use cases out of the box. For instance, you might want to:
Add timestamps to your logs for better traceability.
Prefix logs with custom identifiers to differentiate between different sources or modules.
Handle various types of log messages (strings, objects, arrays) gracefully.
The Insight
The custom transport addresses these needs by:
Handling Different Message Types: It can process simple text messages, arrays, and objects, ensuring that each type is displayed appropriately in Reactotron.
Adding Metadata: It includes the log level and an optional timestamp in the metadata.
Custom Prefixes: It allows you to add a custom prefix to each log message, making it easier to identify the source of the log.
Importance Flag: It marks important logs (based on severity) to make them stand out in Reactotron.
Here's a breakdown of the code:
/**
* Custom transport for sending logs to Reactotron with enhanced features
*/
export const reactotronTransport: transportFunctionType<{
showTimestamp?: boolean;
customPrefix?: string;
}> = (props) => {
const { level, msg, rawMsg, options = {} } = props;
const isImportant = level.severity >= 3;
const prefix = options.customPrefix ? `${options.customPrefix}: ` : '';
// Enhanced message handling
let displayMessage: any;
let previewText = '';
// Case 1: Array of arguments (like console.log('text', object))
if (Array.isArray(rawMsg)) {
const firstItem = rawMsg[0];
const restItems = rawMsg.slice(1);
if (typeof firstItem === 'string' && restItems.length > 0) {
previewText = firstItem;
displayMessage = {
message: firstItem,
data: restItems.length === 1 ? restItems[0] : restItems,
};
} else {
previewText = `Array[${rawMsg.length}]`;
displayMessage = rawMsg;
}
}
// Case 2: Single object (including array)
else if (typeof rawMsg === 'object' && rawMsg !== null) {
if (Array.isArray(rawMsg)) {
previewText = `Array[${rawMsg.length}]`;
} else {
previewText = Object.prototype.toString.call(rawMsg).slice(8, -1);
}
displayMessage = rawMsg;
}
// Case 3: Simple text message
else {
previewText = msg;
displayMessage = rawMsg !== undefined ? rawMsg : msg;
}
// Metadata
const metadata = {
level: level.text,
timestamp: options.showTimestamp ? new Date().toISOString() : undefined,
};
// Preview with prefix
const preview = `${prefix}${previewText}`;
// Send to Reactotron
Reactotron.display({
name: level.text.toUpperCase(),
value: {
...(typeof displayMessage === 'object'
? displayMessage
: { message: displayMessage }),
...metadata,
},
preview,
important: isImportant,
});
};
Why It Matters
This custom transport makes your logging more flexible and informative. By adding timestamps and custom prefixes, you can better track and differentiate logs. The enhanced message handling ensures that all types of log data are displayed correctly in Reactotron, making debugging and monitoring more efficient.
Subscribe to my newsletter
Read articles from Hermann Kao directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Hermann Kao
Hermann Kao
Software developer documenting my journey through web and mobile development. I share what I learn, build, and struggle with—from React to SwiftUI, architecture decisions to deployment challenges. Not an expert, just passionate about coding and learning in public. Join me as I navigate the tech landscape one commit at a time.