|
All checks were successful
I'll read the PR template and fill it out based on the current branch changes.## Description This PR adds support for console logging by introducing a new `createConsoleLogger` function. This logger outputs formatted log messages directly to the JavaScript console using `console.log`, `console.warn`, `console.error`, and `console.debug` methods. It's particularly useful for development environments where React Native debuggers or browser developer tools are attached. The PR also removes the CHANGELOG.md file in favor of using the [releases](https://git.van-hemmen.com/openrn/react-native-logging-tools/releases) tab for version history tracking. ## Type of Change - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [x] Documentation update - [ ] Performance improvement - [ ] Refactoring (no functional changes) - [ ] CI/CD update ## Related Issue Fixes #46 ## Testing - [x] Unit tests added/updated - [x] Manual testing performed - [x] Tested on iOS - [x] Tested on Android ## Breaking Changes N/A - This is a non-breaking additive change. The new `createConsoleLogger` function is optional and does not affect existing functionality. ## Checklist - [x] Code follows the project's code style (Prettier, ESLint) - [x] TypeScript types are properly defined - [x] Tests pass locally - [x] Documentation updated (if needed) - [x] CI checks pass (Prettier, TypeScript, Lint, Tests, Sonar) Reviewed-on: #50 |
||
|---|---|---|
| .devcontainer | ||
| .forgejo | ||
| scripts | ||
| src | ||
| .prettierignore | ||
| .editorconfig | ||
| .gitattributes | ||
| .gitignore | ||
| .npmignore | ||
| .prettierignore | ||
| .prettierrc | ||
| .travis.yml | ||
| babel.config.js | ||
| CODE_OF_CONDUCT.md | ||
| CONTRIBUTING.md | ||
| eslint.config.mjs | ||
| index.d.ts | ||
| jest.config.js | ||
| LICENSE | ||
| package.json | ||
| README.md | ||
| REFERENCE_API.md | ||
| sonar-project.properties | ||
| tsconfig.json | ||
| yarn.lock | ||
React Native Logging Tools
Note: This library is a fork based on the work done on the original react-native-logging-tools.
A unified logging solution for React Native applications that simplifies integration with multiple analytics and error reporting services.
✨ Features
- 📊 Multi-Service Analytics - Send logs to multiple analytics services simultaneously
- 🔥 Error Reporting - Unified error reporting across multiple crash reporting services
- 🐛 Debug Tools - Easy Reactotron integration for development
- ⚡ Global Error Handler - Automatically capture and report fatal JavaScript errors
- 🎯 Type-Safe - Written in TypeScript with full type definitions
- 🎛️ Flexible Configuration - Exclude specific log types from specific services
- 🔒 Sensitive Data Protection - Built-in support for sensitive builds
📋 Table of Contents
- Supported Libraries
- Installation
- Quick Start
- Usage
- Advanced Configuration
- API Documentation
- Examples
- Contributing
- License
🔌 Supported Libraries
| Library | Status | Minimum Version |
|---|---|---|
| Analytics | ||
| Console Logger | ✅ | Built-in |
| Firebase Analytics | ✅ | >= 6.0.0 |
| Instabug | ✅ | >= 9.0.0 |
| Sentry | ✅ | >= 1.3.0 |
| Tealium | ✅ | >= 2.0.2 |
| Reactotron | ✅ | >= 4.0.0 |
| Error Reporting | ||
| Firebase Crashlytics | ✅ | >= 6.0.0 |
| Sentry | ✅ | >= 1.3.0 |
📦 Installation
Configure the Registry
This package is hosted on a private Forgejo npm registry. You need to configure your package manager to use the correct registry for the @openrn scope.
Using npm
Create or edit .npmrc in your project root:
@openrn:registry=https://git.van-hemmen.com/api/packages/openrn/npm/
Using Yarn (v1 Classic)
Create or edit .yarnrc in your project root:
"@openrn:registry" "https://git.van-hemmen.com/api/packages/openrn/npm/"
Using Yarn (v2+/Berry)
Create or edit .yarnrc.yml in your project root:
npmScopes:
openrn:
npmRegistryServer: "https://git.van-hemmen.com/api/packages/openrn/npm/"
Install the Package
# Using yarn
yarn add @openrn/react-native-logging-tools
# Using npm
npm install @openrn/react-native-logging-tools
Peer Dependencies
Install the logging services you want to use:
# Firebase (Analytics + Crashlytics)
yarn add @react-native-firebase/app @react-native-firebase/analytics @react-native-firebase/crashlytics
# Sentry
yarn add @sentry/react-native
# Instabug
yarn add instabug-reactnative
# Tealium
yarn add tealium-react-native
# Reactotron (for development)
yarn add --dev reactotron-react-native
Note: You only need to install the libraries you plan to use. Follow each library's setup guide to configure native dependencies.
🚀 Quick Start
Basic Setup
import { init, createConsoleLogger, createFirebaseLogger, createCrashlyticsLogger, logEvent } from '@openrn/react-native-logging-tools';
import analytics from '@react-native-firebase/analytics';
import crashlytics from '@react-native-firebase/crashlytics';
// Initialize in your app entry point (App.tsx or index.js)
init({
config: {
reportJSErrors: !__DEV__, // Enable automatic crash reporting in production
},
analytics: [
createConsoleLogger(), // Simple console logging
createFirebaseLogger(analytics()),
],
errorReporters: [
createCrashlyticsLogger(crashlytics()),
],
});
// Use anywhere in your app
logEvent('user_login', { method: 'email' });
With Multiple Services
import {
init,
createFirebaseLogger,
createCrashlyticsLogger,
createInstabugLogger,
createSentryLogger,
} from '@openrn/react-native-logging-tools';
import analytics from '@react-native-firebase/analytics';
import crashlytics from '@react-native-firebase/crashlytics';
import Instabug from 'instabug-reactnative';
import * as Sentry from '@sentry/react-native';
init({
config: {
reportJSErrors: !__DEV__,
},
analytics: [
createFirebaseLogger(analytics()),
createInstabugLogger(Instabug, { token: 'YOUR_INSTABUG_TOKEN' }),
createSentryLogger(Sentry, { dsn: 'YOUR_SENTRY_DSN' }),
],
errorReporters: [
createCrashlyticsLogger(crashlytics()),
createSentryLogger(Sentry, { dsn: 'YOUR_SENTRY_DSN' }),
],
});
📖 Usage
Initialization
Initialize the library before using any logging functions, typically in your app's entry point:
import { init } from '@openrn/react-native-logging-tools';
init({
config: {
reportJSErrors: !__DEV__, // Automatic JS error reporting
isSensitiveBuild: false, // Prevent logging sensitive data
Reactotron, // Optional: for Reactotron integration
AsyncStorage, // Optional: for Reactotron persistence
excludeLogs: { // Optional: exclude log types per service
instabug: [DEBUG_LOG],
firebase: [NETWORK_LOG],
},
},
analytics: [/* logger functions */],
errorReporters: [/* error reporter functions */],
});
📚 Full initialization documentation →
Logging Events
The library provides several logging functions for different event types:
Basic Event Logging
import { logEvent } from '@openrn/react-native-logging-tools';
// Simple event
logEvent('button_clicked');
// Event with parameters
logEvent('product_viewed', {
productId: '12345',
category: 'electronics',
price: 299.99,
});
// Sensitive event (won't log if isSensitiveBuild is true)
logEvent('payment_info_entered', { method: 'card' }, true);
Categorized Logging
Use categorized log functions that automatically prefix events for better organization:
import {
logDebugEvent,
logWarningEvent,
logNetworkEvent,
logErrorEvent,
} from '@openrn/react-native-logging-tools';
// Debug event (prefixed with "D/")
logDebugEvent('api_response', { status: 200, duration: 234 });
// Logs as: "D/ api_response"
// Warning event (prefixed with "W/")
logWarningEvent('slow_query', { query: 'users', duration: 5000 });
// Logs as: "W/ slow_query"
// Network event (prefixed with "N/")
logNetworkEvent('api_call', { endpoint: '/users', method: 'GET' });
// Logs as: "N/ api_call"
// Error event (prefixed with "E/")
logErrorEvent('validation_failed', { field: 'email', reason: 'invalid format' });
// Logs as: "E/ validation_failed"
📚 Full logging documentation →
Error Reporting
Report errors to all configured error reporting services:
import { recordError } from '@openrn/react-native-logging-tools';
try {
// Your code
processPayment(amount);
} catch (error) {
recordError('payment_processing_failed', {
amount,
userId: user.id,
error: error.message,
stack: error.stack,
});
}
Automatic Error Reporting
When reportJSErrors is enabled, fatal JavaScript errors are automatically captured and sent to all error reporters:
init({
config: {
reportJSErrors: !__DEV__, // Enable in production
},
errorReporters: [
createCrashlyticsLogger(crashlytics()),
createSentryLogger(Sentry, { dsn: 'YOUR_DSN' }),
],
});
// All uncaught errors will be automatically reported
📚 Full error reporting documentation →
Reactotron Integration
Reactotron is a debugging tool for React Native. This library makes integration simple:
Basic Setup
import Reactotron from './ReactotronConfig';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { init, createReactotronLogger } from '@openrn/react-native-logging-tools';
init({
config: {
Reactotron,
AsyncStorage,
},
analytics: [
createReactotronLogger(Reactotron),
],
});
Redux Integration
import { createStore, compose } from 'redux';
import { setupReactotron } from '@openrn/react-native-logging-tools';
import reactotronRedux from 'reactotron-redux';
const store = createStore(
rootReducer,
compose(
setupReactotron(
{ name: 'MyApp', host: 'localhost' },
[reactotronRedux()]
).createEnhancer()
)
);
📚 Full Reactotron documentation →
Console Logger
The console logger is a built-in, zero-dependency logger that outputs events directly to the JavaScript console. It's perfect for development and debugging.
Basic Usage
import { init, createConsoleLogger } from '@openrn/react-native-logging-tools';
init({
analytics: [
createConsoleLogger(),
],
});
How It Works
The console logger automatically uses the appropriate console method based on the event type:
- Debug events (
logDebugEvent) →console.log() - Warning events (
logWarningEvent) →console.warn() - Error events (
logErrorEvent) →console.error() - General events (
logEvent) →console.log()
Example
import {
init,
createConsoleLogger,
logDebugEvent,
logWarningEvent,
logErrorEvent,
logEvent,
} from '@openrn/react-native-logging-tools';
init({
analytics: [createConsoleLogger()],
});
logDebugEvent('user_action', { action: 'click' });
// Console output: "D/ user_action"
logWarningEvent('slow_response', { duration: 5000 });
// Console output (warning): "W/ slow_response"
logErrorEvent('api_failure', { code: 500 });
// Console output (error): "E/ api_failure"
logEvent('custom_event', { data: 'value' });
// Console output: "custom_event"
Filtering Console Logs
You can exclude specific log types from console output using the excludeLogs configuration:
import { init, createConsoleLogger, DEBUG_LOG, NETWORK_LOG } from '@openrn/react-native-logging-tools';
init({
config: {
excludeLogs: {
console: [DEBUG_LOG, NETWORK_LOG], // Don't log debug or network events to console
},
},
analytics: [createConsoleLogger()],
});
📚 Full console logger documentation →
⚙️ Advanced Configuration
Excluding Log Types
Exclude specific log types from specific services:
import { init, DEBUG_LOG, NETWORK_LOG, WARNING_LOG, ERROR_LOG } from '@openrn/react-native-logging-tools';
init({
config: {
excludeLogs: {
// Don't send debug logs to console
console: [DEBUG_LOG],
// Don't send debug logs to Instabug
instabug: [DEBUG_LOG],
// Don't send network logs to Firebase
firebase: [NETWORK_LOG],
// Don't send debug or warning logs to Sentry
sentry: [DEBUG_LOG, WARNING_LOG],
},
},
analytics: [/* ... */],
});
Log type constants:
DEBUG_LOG = 0- Debug events (logDebugEvent)WARNING_LOG = 1- Warning events (logWarningEvent)NETWORK_LOG = 2- Network events (logNetworkEvent)ERROR_LOG = 3- Error events (logErrorEvent)
Sensitive Data Protection
Prevent logging sensitive data in production builds:
init({
config: {
isSensitiveBuild: true, // Set to true for production builds
},
analytics: [/* ... */],
});
// This will NOT be logged when isSensitiveBuild is true
logEvent('credit_card_entered', { last4: '1234' }, true);
// This WILL be logged regardless of isSensitiveBuild
logEvent('screen_viewed', { screen: 'checkout' }, false);
React Navigation Integration
Track navigation events automatically:
import { NavigationContainer } from '@react-navigation/native';
import { logEvent } from '@openrn/react-native-logging-tools';
function App() {
const navigationRef = useNavigationContainerRef();
return (
<NavigationContainer
ref={navigationRef}
onStateChange={() => {
const currentRoute = navigationRef.getCurrentRoute();
logEvent('screen_view', {
screen_name: currentRoute?.name,
screen_params: currentRoute?.params,
});
}}
>
{/* Your app */}
</NavigationContainer>
);
}
📚 API Documentation
Complete API reference with all methods, parameters, and examples:
Core Functions
init()- Initialize the librarylogEvent()- Log a general eventlogDebugEvent()- Log a debug eventlogWarningEvent()- Log a warning eventlogNetworkEvent()- Log a network eventlogErrorEvent()- Log an error eventrecordError()- Record an error
Logger Creation
createConsoleLogger()createFirebaseLogger()createCrashlyticsLogger()createInstabugLogger()createSentryLogger()createTealiumLogger()createReactotronLogger()setupReactotron()
💡 Examples
Complete App Setup
// App.tsx
import React from 'react';
import {
init,
createConsoleLogger,
createFirebaseLogger,
createCrashlyticsLogger,
createInstabugLogger,
createReactotronLogger,
DEBUG_LOG,
} from '@openrn/react-native-logging-tools';
import analytics from '@react-native-firebase/analytics';
import crashlytics from '@react-native-firebase/crashlytics';
import Instabug from 'instabug-reactnative';
import Reactotron from './ReactotronConfig';
import AsyncStorage from '@react-native-async-storage/async-storage';
// Initialize logging
init({
config: {
Reactotron,
AsyncStorage,
reportJSErrors: !__DEV__,
isSensitiveBuild: false,
excludeLogs: {
instabug: [DEBUG_LOG], // Don't spam Instabug with debug logs
},
},
analytics: [
createConsoleLogger(), // Always log to console for debugging
createFirebaseLogger(analytics()),
createInstabugLogger(Instabug, {
token: process.env.INSTABUG_TOKEN,
invocationEvent: Instabug.invocationEvent.shake,
}),
...__DEV__ ? [createReactotronLogger(Reactotron)] : [],
],
errorReporters: [
createCrashlyticsLogger(crashlytics()),
],
});
export default function App() {
return <YourApp />;
}
E-commerce Tracking
import { logEvent, logErrorEvent } from '@openrn/react-native-logging-tools';
// Product view
function ProductScreen({ product }) {
useEffect(() => {
logEvent('product_viewed', {
productId: product.id,
name: product.name,
category: product.category,
price: product.price,
});
}, [product]);
}
// Add to cart
function addToCart(product, quantity) {
logEvent('add_to_cart', {
productId: product.id,
quantity,
value: product.price * quantity,
});
}
// Purchase
function completePurchase(order) {
logEvent('purchase', {
orderId: order.id,
value: order.total,
currency: 'USD',
items: order.items.length,
});
}
// Error tracking
function handleCheckoutError(error) {
logErrorEvent('checkout_failed', {
step: 'payment',
error: error.message,
userId: user.id,
});
}
API Request Logging
import { logNetworkEvent, logErrorEvent } from '@openrn/react-native-logging-tools';
async function apiRequest(endpoint, options) {
const startTime = Date.now();
try {
const response = await fetch(endpoint, options);
const duration = Date.now() - startTime;
logNetworkEvent('api_request', {
endpoint,
method: options?.method || 'GET',
status: response.status,
duration,
});
return response;
} catch (error) {
logErrorEvent('api_request_failed', {
endpoint,
method: options?.method || 'GET',
error: error.message,
duration: Date.now() - startTime,
});
throw error;
}
}
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
Quick Start for Contributors
# Clone the repository
git clone https://git.van-hemmen.com/openrn/react-native-logging-tools.git
# Install dependencies
yarn install
# Run tests
yarn qa:unit_test
# Run linter
yarn qa:lint
# Run all quality checks
yarn qa:all
Read the full contributing guide →
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🔗 Links
👥 Authors
- Guillaume Van Hemmen
- Imran Mentese
- Soliman Achahbar
- Martin VanLerberghe
Made with ❤️ for the React Native community