Logger Service
Centralized logging service for the Orbitus platform. Provides structured logging with context management.
Services
Logger Service
Centralized logging with context management and multiple log levels.
Basic Usage
import { logger } from '@orbitusdev/core/services/logger';
// Basic logging
logger.info('User logged in', { userId: '123', email: 'user@example.com' });
logger.warn('Cache miss', { key: 'user-data' });
logger.error('Database connection failed', error, { database: 'postgres' });
logger.debug('Processing request', { path: '/api/users' });
logger.critical('System failure', error, { component: 'payment' });Context Management
import { logger } from '@orbitusdev/core/services/logger';
// Set global context
logger.setContext({
userId: 'user-123',
sessionId: 'session-456',
ip: '192.168.1.1',
userAgent: 'Mozilla/5.0...',
requestId: 'req-789',
});
// Set individual context
logger.setUserId('user-123');
logger.setSessionId('session-456');
logger.setRequestContext('192.168.1.1', 'Mozilla/5.0...', 'req-789');
// Clear context
logger.clearContext();
logger.clearUserId();
// Get current context
const context = logger.getContext();User Actions
import { logger } from '@orbitusdev/core/services/logger';
// Track user actions
logger.logUserAction('button_click', 'checkout-button', {
page: '/products',
product: 'premium-plan',
});
// Predefined actions
logger.logLogin('google'); // 'email' | 'google' | 'github'
logger.logLogout();
logger.logPageView('/dashboard');
logger.logFeatureUsage('export-data', { format: 'csv' });
logger.logApiCall('/api/users', 'POST', 201);Device & Performance Tracking
import { logger } from '@orbitusdev/core/services/logger';
// Log device info
logger.logDeviceInfo({
deviceType: 'mobile',
browser: 'Chrome',
os: 'Android',
});
// Log performance metrics
logger.logPerformance('page-load', 1234, {
route: '/dashboard',
ttfb: 200,
});Session & Security
import { logger } from '@orbitusdev/core/services/logger';
// Session tracking
logger.logSessionStart('session-123');
logger.logSessionTerminate('session-123', 'user');
// Security events
logger.logSecurityEvent('failed-login', {
ip: '192.168.1.1',
userAgent: 'Mozilla/5.0...',
severity: 'medium',
});Track API Calls
import { trackApiCallWithLogging } from '@orbitusdev/core/utils/observability';
const response = await trackApiCallWithLogging('fetch-products', {
execute: async () => {
return await fetch('/api/products');
},
method: 'GET',
url: '/api/products',
metadata: { category: 'electronics' },
});Track Database Queries
import { trackDatabaseQueryWithLogging } from '@orbitusdev/core/utils/observability';
const posts = await trackDatabaseQueryWithLogging('list-posts', {
execute: async () => {
return await prisma.post.findMany();
},
operation: 'findMany',
table: 'posts',
metadata: { status: 'published' },
});Email Service
Multi-provider email service with templating and rate limiting.
Initialize Service
import { getEmailService } from '@orbitusdev/core/services/email';
const emailService = getEmailService();Send Email
import { getEmailService } from '@orbitusdev/core/services/email';
const emailService = getEmailService();
const result = await emailService.sendEmail({
to: 'user@example.com',
subject: 'Welcome to Orbitus',
html: '<h1>Welcome!</h1><p>Thanks for signing up.</p>',
text: 'Welcome! Thanks for signing up.',
from: 'noreply@orbitus.dev',
replyTo: 'support@orbitus.dev',
tags: { category: 'welcome', user_type: 'new' },
});
if (result.success) {
console.log('Email sent:', result.messageId);
} else {
console.error('Email failed:', result.error);
}Email Templates
import { getEmailService } from '@orbitusdev/core/services/email';
const emailService = getEmailService();
// Register template
emailService.registerTemplate({
id: 'welcome',
subject: 'Welcome {{name}}!',
html: '<h1>Hello {{name}}</h1><p>Your email is {{email}}</p>',
text: 'Hello {{name}}! Your email is {{email}}',
from: 'noreply@orbitus.dev',
});
// Send with template
const result = await emailService.sendEmailWithTemplate(
'welcome',
{ to: 'user@example.com' },
{ name: 'John Doe', email: 'user@example.com' }
);Bulk Emails
import { getEmailService } from '@orbitusdev/core/services/email';
const emailService = getEmailService();
const emails = [
{ to: 'user1@example.com', subject: 'Newsletter', html: '...' },
{ to: 'user2@example.com', subject: 'Newsletter', html: '...' },
{ to: 'user3@example.com', subject: 'Newsletter', html: '...' },
];
const result = await emailService.sendBulkEmails(emails, 10); // 10 per batch
console.log(`Sent: ${result.successful}/${result.total}`);
console.log(`Failed: ${result.failed}`);SMS Service
Multi-provider SMS service with rate limiting.
import { getSMSService } from '@orbitusdev/core/services/sms';
const smsService = getSMSService();
const result = await smsService.sendSMS({
to: '+905551234567',
message: 'Your verification code is: 123456',
});
if (result.success) {
console.log('SMS sent:', result.messageId);
}Utilities
Cache
Redis-based caching utilities with automatic key generation.
import {
cacheGet,
cacheInvalidate,
cacheInvalidatePrefix,
cacheKey,
cacheSet,
} from '@orbitusdev/core';
// Generate cache key
const key = cacheKey(['user', userId, 'profile']);
// Result: "user:123:profile"
// Set cache (5 minutes TTL)
cacheSet(key, userData, 300);
// Get cache
const cached = cacheGet<User>(key);
if (cached !== undefined) {
return cached;
}
// Invalidate single key
cacheInvalidate(key);
// Invalidate by prefix
cacheInvalidatePrefix('user:123');Rate Limiting
Upstash-based rate limiting for API, auth, email, and SMS.
import { rateLimitManager } from '@orbitusdev/core/lib/security';
// Check API rate limit
const result = await rateLimitManager.checkApiRateLimit('user-123');
if (!result.success) {
throw new Error('Rate limit exceeded');
}
// Check auth rate limit (5 attempts per 15 minutes)
const authResult = await rateLimitManager.checkAuthRateLimit('192.168.1.1');
// Check email resend rate limit (3 per hour)
const emailResult = await rateLimitManager.checkEmailResendRateLimit('user@example.com');
// Check SMS rate limit (5 per hour)
const smsResult = await rateLimitManager.checkSmsRateLimit('+905551234567');
// Check availability
if (rateLimitManager.isAvailable()) {
// Redis is configured
}Sanitization
Input sanitization for security.
import { sanitizeEmailTags, sanitizeHtml } from '@orbitusdev/core/lib/security';
// Sanitize HTML
const clean = sanitizeHtml('<script>alert("xss")</script><p>Hello</p>');
// Result: "<p>Hello</p>"
// Sanitize email tags
const tags = sanitizeEmailTags({
'user-id': '123',
'<script>': 'malicious',
valid_tag: 'good',
});
// Result: { 'user-id': '123', valid_tag: 'good' }Formatters
Format numbers, currency, and phone numbers.
import {
formatCompactNumber,
formatCurrency,
formatNumber,
formatPercent,
formatPhoneNumber,
} from '@orbitusdev/core/utils/formatters';
// Number formatting
formatNumber(1234567.89, 'tr-TR'); // "1.234.567,89"
formatNumber(1234567.89, 'en-US'); // "1,234,567.89"
// Currency
formatCurrency(1234.56, 'USD', 'en-US'); // "$1,234.56"
formatCurrency(1234.56, 'TRY', 'tr-TR'); // "₺1.234,56"
// Percent
formatPercent(0.1234, 'en-US'); // "12.34%"
// Compact numbers
formatCompactNumber(1234567, 'en-US'); // "1.2M"
formatCompactNumber(1234, 'en-US'); // "1.2K"
// Phone numbers
formatPhoneNumber('+905551234567', 'INTERNATIONAL'); // "+90 555 123 45 67"
formatPhoneNumber('05551234567', 'NATIONAL', 'TR'); // "0555 123 45 67"Error Handling
Standardized error utilities.
import {
AppError,
createAppError,
handleError,
isAppError,
NotFoundError,
UnauthorizedError,
ValidationError,
} from '@orbitusdev/core/utils/error';
// Throw custom errors
throw new ValidationError('Invalid email address');
throw new NotFoundError('User not found');
throw new UnauthorizedError('Access denied');
// Create with factory
throw createAppError('VALIDATION_ERROR', 'Invalid input', { field: 'email' });
// Handle errors
try {
// ...
} catch (error) {
handleError(error); // Logs and formats error
}
// Check error type
if (isAppError(error)) {
console.log(error.code, error.statusCode);
}Delay Utility
Promise-based delay utility.
import { delay } from '@orbitusdev/core/utils';
// Wait 1 second
await delay(1000);
// Retry with delay
for (let i = 0; i < 3; i++) {
try {
await fetchData();
break;
} catch (error) {
if (i < 2) await delay(1000 * Math.pow(2, i)); // Exponential backoff
}
}Class Names Utility
Merge Tailwind CSS classes safely.
import { cn } from '@orbitusdev/core/utils';
const buttonClass = cn(
'px-4 py-2 rounded',
isActive && 'bg-blue-500 text-white',
isDisabled && 'opacity-50 cursor-not-allowed'
);React Hooks
useHotkeys
Keyboard shortcut management.
import { useHotkeys } from '@orbitusdev/core/hooks';
function SearchBar() {
const inputRef = useRef<HTMLInputElement>(null);
useHotkeys('cmd+k, ctrl+k', (e) => {
e.preventDefault();
inputRef.current?.focus();
});
return <input ref={inputRef} placeholder="Search..." />;
}useMobile
Detect mobile devices.
import { useMobile } from '@orbitusdev/core/hooks';
function ResponsiveNav() {
const isMobile = useMobile();
return isMobile ? <MobileMenu /> : <DesktopMenu />;
}useStickyNavbar
Sticky navbar on scroll.
import { useStickyNavbar } from '@orbitusdev/core/hooks';
function Navbar() {
const isSticky = useStickyNavbar(100); // Sticky after 100px scroll
return (
<nav className={isSticky ? 'fixed top-0 shadow-lg' : ''}>
{/* ... */}
</nav>
);
}useClickOutside
Detect clicks outside an element.
import { useClickOutside } from '@orbitusdev/core/hooks';
function Dropdown() {
const [isOpen, setIsOpen] = useState(false);
const ref = useRef(null);
useClickOutside(ref, () => setIsOpen(false));
return (
<div ref={ref}>
<button onClick={() => setIsOpen(!isOpen)}>Toggle</button>
{isOpen && <Menu />}
</div>
);
}useShoppingCart
Shopping cart state management.
import { useShoppingCart } from '@orbitusdev/core/hooks';
function ProductPage() {
const {
cart,
addItem,
removeItem,
updateQuantity,
clearCart,
totalItems,
totalPrice
} = useShoppingCart();
return (
<div>
<button onClick={() => addItem({ id: '1', name: 'Product', price: 29.99, quantity: 1 })}>
Add to Cart
</button>
<p>Total: ${totalPrice.toFixed(2)} ({totalItems} items)</p>
</div>
);
}useCookieConsent
Cookie consent management.
import { useCookieConsent } from '@orbitusdev/core/hooks';
function CookieBanner() {
const { consent, acceptAll, rejectAll, acceptCategory, hasConsented } = useCookieConsent();
if (hasConsented) return null;
return (
<div>
<button onClick={acceptAll}>Accept All</button>
<button onClick={() => acceptCategory('analytics')}>Analytics Only</button>
<button onClick={rejectAll}>Reject All</button>
</div>
);
}useCanvasConfetti
Confetti animations.
import { useCanvasConfetti } from '@orbitusdev/core/hooks';
function SuccessPage() {
const confetti = useCanvasConfetti();
const celebrate = () => {
confetti({
particleCount: 100,
spread: 70,
origin: { y: 0.6 }
});
};
return <button onClick={celebrate}>Celebrate! 🎉</button>;
}useHoverEffects
Hover effects with Framer Motion.
import { useHoverEffects } from '@orbitusdev/core/hooks';
function Card() {
const { ref, controls } = useHoverEffects();
return (
<motion.div ref={ref} animate={controls}>
Hover me!
</motion.div>
);
}SEO Utilities
Metadata Generation
import { generateMetadata } from '@orbitusdev/core/seo';
export const metadata = generateMetadata({
title: 'Home',
description: 'Welcome to Orbitus',
path: '/',
keywords: ['nextjs', 'react', 'typescript'],
images: [{ url: '/og-image.jpg', width: 1200, height: 630 }],
});Sitemap Generation
import { generateSitemap } from '@orbitusdev/core/seo';
export default function sitemap() {
return generateSitemap([
{ path: '/', priority: 1.0 },
{ path: '/about', priority: 0.8 },
{ path: '/blog', priority: 0.7 },
]);
}Robots.txt
import { generateRobots } from '@orbitusdev/core/seo';
export default function robots() {
return generateRobots({
sitemapUrl: 'https://orbitus.dev/sitemap.xml',
});
}Best Practices
- Track important operations: Use trackWithLogging for critical flows
- Cache strategically: Cache expensive operations with appropriate TTL
- Rate limit endpoints: Protect sensitive endpoints with rate limiting
- Sanitize inputs: Always sanitize user inputs before processing
- Handle errors gracefully: Use AppError for consistent error handling
Environment Variables
# Logger
LOG_LEVEL=info
NEXT_PUBLIC_LOG_PROVIDER=console
# Email
EMAIL_PROVIDER=resend
RESEND_API_KEY=re_...
RESEND_FROM_EMAIL=noreply@orbitus.dev
# SMS
SMS_PROVIDER=twilio
TWILIO_ACCOUNT_SID=...
TWILIO_AUTH_TOKEN=...
TWILIO_PHONE_NUMBER=...
# Rate Limiting
UPSTASH_REDIS_REST_URL=...
UPSTASH_REDIS_REST_TOKEN=...