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:
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}: ` : '';
let displayMessage: any;
let previewText = '';
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;
}
}
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;
}
else {
previewText = msg;
displayMessage = rawMsg !== undefined ? rawMsg : msg;
}
const metadata = {
level: level.text,
timestamp: options.showTimestamp ? new Date().toISOString() : undefined,
};
const preview = `${prefix}${previewText}`;
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.