diff --git a/docs/platforms/android/logs/index.mdx b/docs/platforms/android/logs/index.mdx index 49c3ed812c5d0..dc8ad25120115 100644 --- a/docs/platforms/android/logs/index.mdx +++ b/docs/platforms/android/logs/index.mdx @@ -27,6 +27,10 @@ With Sentry Structured Logs, you can send text-based log information from your a +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/apple/common/logs/index.mdx b/docs/platforms/apple/common/logs/index.mdx index 831641634dd14..c5ea6a573a452 100644 --- a/docs/platforms/apple/common/logs/index.mdx +++ b/docs/platforms/apple/common/logs/index.mdx @@ -23,6 +23,10 @@ With Sentry Structured Logs, you can send text-based log information from your a +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/dart/common/logs/index.mdx b/docs/platforms/dart/common/logs/index.mdx index 49c3ed812c5d0..dc8ad25120115 100644 --- a/docs/platforms/dart/common/logs/index.mdx +++ b/docs/platforms/dart/common/logs/index.mdx @@ -27,6 +27,10 @@ With Sentry Structured Logs, you can send text-based log information from your a +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/dart/guides/flutter/logs/index.mdx b/docs/platforms/dart/guides/flutter/logs/index.mdx index 831641634dd14..c5ea6a573a452 100644 --- a/docs/platforms/dart/guides/flutter/logs/index.mdx +++ b/docs/platforms/dart/guides/flutter/logs/index.mdx @@ -23,6 +23,10 @@ With Sentry Structured Logs, you can send text-based log information from your a +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/dotnet/common/logs/index.mdx b/docs/platforms/dotnet/common/logs/index.mdx index d7670fc0e1ef5..240c7b0c7d7ab 100644 --- a/docs/platforms/dotnet/common/logs/index.mdx +++ b/docs/platforms/dotnet/common/logs/index.mdx @@ -34,6 +34,10 @@ With Sentry Structured Logs, you can send text-based log information from your a +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/go/common/logs/index.mdx b/docs/platforms/go/common/logs/index.mdx index 8addf4742a413..759a441ffb326 100644 --- a/docs/platforms/go/common/logs/index.mdx +++ b/docs/platforms/go/common/logs/index.mdx @@ -33,6 +33,10 @@ If the `Debug` init option is set to true, calls to the `sentry.Logger` will als +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/godot/logs/index.mdx b/docs/platforms/godot/logs/index.mdx index 85bcaaa43e19a..81bcb8c5c57a9 100644 --- a/docs/platforms/godot/logs/index.mdx +++ b/docs/platforms/godot/logs/index.mdx @@ -23,6 +23,10 @@ With Sentry Structured Logs, you can send text-based log information from your G +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/java/common/logs/index.mdx b/docs/platforms/java/common/logs/index.mdx index 8d2099215e36b..ced862a2549c8 100644 --- a/docs/platforms/java/common/logs/index.mdx +++ b/docs/platforms/java/common/logs/index.mdx @@ -29,6 +29,10 @@ With Sentry Structured Logs, you can send text-based log information from your a +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/javascript/common/logs/index.mdx b/docs/platforms/javascript/common/logs/index.mdx index ce5229f21c055..63d46e3da3404 100644 --- a/docs/platforms/javascript/common/logs/index.mdx +++ b/docs/platforms/javascript/common/logs/index.mdx @@ -34,6 +34,10 @@ With Sentry Structured Logs, you can send text-based log information from your a +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/javascript/guides/nextjs/logs/index.mdx b/docs/platforms/javascript/guides/nextjs/logs/index.mdx index 96fd7db9548f9..4cfce246c5135 100644 --- a/docs/platforms/javascript/guides/nextjs/logs/index.mdx +++ b/docs/platforms/javascript/guides/nextjs/logs/index.mdx @@ -160,110 +160,7 @@ Sentry.withScope((scope) => { ## Best Practices - - - - -### Wide Events Over Scattered Logs - -Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. - -This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. - - - - -```typescript -// ❌ Scattered thin logs -Sentry.logger.info("Starting checkout"); -Sentry.logger.info("Validating cart"); -Sentry.logger.info("Processing payment"); -Sentry.logger.info("Checkout complete"); - -// ✅ One wide event with full context -Sentry.logger.info("Checkout completed", { - orderId: order.id, - userId: user.id, - userTier: user.subscription, - cartValue: cart.total, - itemCount: cart.items.length, - paymentMethod: "stripe", - duration: Date.now() - startTime, -}); -``` - - - - - - - -### Include Business Context - -Add attributes that help you prioritize and debug: - -- **User context** — tier, account age, lifetime value -- **Transaction data** — order value, item count -- **Feature state** — active feature flags -- **Request metadata** — endpoint, method, duration - -This lets you filter logs by high-value customers or specific features. - - - - -```typescript -Sentry.logger.info("API request completed", { - // User context - userId: user.id, - userTier: user.plan, // "free" | "pro" | "enterprise" - accountAgeDays: user.ageDays, - - // Request data - endpoint: "/api/orders", - method: "POST", - duration: 234, - - // Business context - orderValue: 149.99, - featureFlags: ["new-checkout", "discount-v2"], -}); -``` - - - - - - - -### Consistent Attribute Naming - -Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. - -**Recommended:** Use `snake_case` for custom attributes to match common conventions. - - - - -```typescript -// ❌ Inconsistent naming -{ user: "123" } -{ userId: "123" } -{ user_id: "123" } -{ UserID: "123" } - -// ✅ Consistent snake_case -{ - user_id: "123", - order_id: "456", - cart_value: 99.99, - item_count: 3, -} -``` - - - - + ## Integrations diff --git a/docs/platforms/native/logs/index.mdx b/docs/platforms/native/logs/index.mdx index 32140b4a29f89..132ac6db97c8e 100644 --- a/docs/platforms/native/logs/index.mdx +++ b/docs/platforms/native/logs/index.mdx @@ -23,6 +23,10 @@ With Sentry Structured Logs, you can send text-based log information from your a +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/php/common/logs/index.mdx b/docs/platforms/php/common/logs/index.mdx index 06e7a95734994..74de1abf3acfc 100644 --- a/docs/platforms/php/common/logs/index.mdx +++ b/docs/platforms/php/common/logs/index.mdx @@ -29,6 +29,10 @@ With Sentry Structured Logs, you can send text-based log information from your a +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/php/guides/laravel/logs/index.mdx b/docs/platforms/php/guides/laravel/logs/index.mdx index 8947f0d1ff259..cc18b57942107 100644 --- a/docs/platforms/php/guides/laravel/logs/index.mdx +++ b/docs/platforms/php/guides/laravel/logs/index.mdx @@ -24,6 +24,10 @@ With Sentry Structured Logs, you can send text-based log information from your L +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/python/logs/index.mdx b/docs/platforms/python/logs/index.mdx index 8726e669e654a..c06cc3902d970 100644 --- a/docs/platforms/python/logs/index.mdx +++ b/docs/platforms/python/logs/index.mdx @@ -29,6 +29,10 @@ With Sentry Structured Logs, you can send text-based log information from your a +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/react-native/logs/index.mdx b/docs/platforms/react-native/logs/index.mdx index 887417ebe5f2c..f9b88b66714e6 100644 --- a/docs/platforms/react-native/logs/index.mdx +++ b/docs/platforms/react-native/logs/index.mdx @@ -29,6 +29,10 @@ With Sentry Structured Logs, you can send text-based log information from your a +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/ruby/guides/rails/logs/index.mdx b/docs/platforms/ruby/guides/rails/logs/index.mdx index 33cca94782966..bb8e89f1366bc 100644 --- a/docs/platforms/ruby/guides/rails/logs/index.mdx +++ b/docs/platforms/ruby/guides/rails/logs/index.mdx @@ -25,6 +25,10 @@ With Sentry Structured Logs, you can send text-based log information from your R +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/ruby/logs/index.mdx b/docs/platforms/ruby/logs/index.mdx index c3e799b8010af..dd5730ec86031 100644 --- a/docs/platforms/ruby/logs/index.mdx +++ b/docs/platforms/ruby/logs/index.mdx @@ -25,6 +25,10 @@ With Sentry Structured Logs, you can send text-based log information from your a +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/rust/common/logs/index.mdx b/docs/platforms/rust/common/logs/index.mdx index b7a60297de1d2..2aa78d33be0b5 100644 --- a/docs/platforms/rust/common/logs/index.mdx +++ b/docs/platforms/rust/common/logs/index.mdx @@ -194,6 +194,10 @@ let _guard = sentry::init(("___PUBLIC_DSN___", sentry::ClientOptions { })); ``` +## Best Practices + + + ## Default Attributes The Rust SDK automatically sets several default attributes on all log entries to provide context and improve debugging: diff --git a/docs/platforms/unity/logs/index.mdx b/docs/platforms/unity/logs/index.mdx index 902b576b38f3f..4ce79a4fc32b9 100644 --- a/docs/platforms/unity/logs/index.mdx +++ b/docs/platforms/unity/logs/index.mdx @@ -23,6 +23,10 @@ With Sentry Structured Logs, you can send text-based log information from your U +## Best Practices + + + ## Default Attributes diff --git a/docs/platforms/unreal/logs/index.mdx b/docs/platforms/unreal/logs/index.mdx index be34c3cb67630..46d673d123b8e 100644 --- a/docs/platforms/unreal/logs/index.mdx +++ b/docs/platforms/unreal/logs/index.mdx @@ -23,6 +23,10 @@ With Sentry Structured Logs, you can send text-based log information from your U +## Best Practices + + + ## Default Attributes diff --git a/platform-includes/logs/best-practices/android.mdx b/platform-includes/logs/best-practices/android.mdx new file mode 100644 index 0000000000000..662684456f268 --- /dev/null +++ b/platform-includes/logs/best-practices/android.mdx @@ -0,0 +1,114 @@ + + + + +### Wide Events Over Scattered Logs + +Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. + +This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. + + + + +```kotlin +// ❌ Scattered thin logs +Sentry.logger().info("Starting checkout") +Sentry.logger().info("Validating cart") +Sentry.logger().info("Processing payment") +Sentry.logger().info("Checkout complete") + +// ✅ One wide event with full context +Sentry.logger().log( + SentryLogLevel.INFO, + SentryLogParameters.create( + SentryAttributes.of( + SentryAttribute.stringAttribute("order_id", order.id), + SentryAttribute.stringAttribute("user_id", user.id), + SentryAttribute.stringAttribute("user_tier", user.subscription), + SentryAttribute.doubleAttribute("cart_value", cart.total), + SentryAttribute.integerAttribute("item_count", cart.items.size), + SentryAttribute.stringAttribute("payment_method", "stripe") + ) + ), + "Checkout completed" +) +``` + + + + + + + +### Include Business Context + +Add attributes that help you prioritize and debug: + +- **User context** — tier, account age, lifetime value +- **Transaction data** — order value, item count +- **Feature state** — active feature flags +- **Request metadata** — endpoint, method, duration + +This lets you filter logs by high-value customers or specific features. + + + + +```kotlin +Sentry.logger().log( + SentryLogLevel.INFO, + SentryLogParameters.create( + SentryAttributes.of( + // User context + SentryAttribute.stringAttribute("user_id", user.id), + SentryAttribute.stringAttribute("user_tier", user.plan), + SentryAttribute.integerAttribute("account_age_days", user.ageDays), + + // Request data + SentryAttribute.stringAttribute("endpoint", "/api/orders"), + SentryAttribute.stringAttribute("method", "POST"), + SentryAttribute.integerAttribute("duration_ms", 234), + + // Business context + SentryAttribute.doubleAttribute("order_value", 149.99) + ) + ), + "API request completed" +) +``` + + + + + + + +### Consistent Attribute Naming + +Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. + +**Recommended:** Use `snake_case` for custom attributes to match common conventions. + + + + +```kotlin +// ❌ Inconsistent naming +SentryAttribute.stringAttribute("user", "123") +SentryAttribute.stringAttribute("userId", "123") +SentryAttribute.stringAttribute("user_id", "123") +SentryAttribute.stringAttribute("UserID", "123") + +// ✅ Consistent snake_case +SentryAttributes.of( + SentryAttribute.stringAttribute("user_id", "123"), + SentryAttribute.stringAttribute("order_id", "456"), + SentryAttribute.doubleAttribute("cart_value", 99.99), + SentryAttribute.integerAttribute("item_count", 3) +) +``` + + + + diff --git a/platform-includes/logs/best-practices/apple.mdx b/platform-includes/logs/best-practices/apple.mdx new file mode 100644 index 0000000000000..8f43b04530dd5 --- /dev/null +++ b/platform-includes/logs/best-practices/apple.mdx @@ -0,0 +1,104 @@ + + + + +### Wide Events Over Scattered Logs + +Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. + +This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. + + + + +```swift +// ❌ Scattered thin logs +SentrySDK.logger.info(message: "Starting checkout") +SentrySDK.logger.info(message: "Validating cart") +SentrySDK.logger.info(message: "Processing payment") +SentrySDK.logger.info(message: "Checkout complete") + +// ✅ One wide event with full context +SentrySDK.logger.info(message: "Checkout completed", attributes: [ + "order_id": order.id, + "user_id": user.id, + "user_tier": user.subscription, + "cart_value": cart.total, + "item_count": cart.items.count, + "payment_method": "stripe", + "duration_ms": Int(Date().timeIntervalSince(startTime) * 1000) +]) +``` + + + + + + + +### Include Business Context + +Add attributes that help you prioritize and debug: + +- **User context** — tier, account age, lifetime value +- **Transaction data** — order value, item count +- **Feature state** — active feature flags +- **Request metadata** — endpoint, method, duration + +This lets you filter logs by high-value customers or specific features. + + + + +```swift +SentrySDK.logger.info(message: "API request completed", attributes: [ + // User context + "user_id": user.id, + "user_tier": user.plan, // "free" | "pro" | "enterprise" + "account_age_days": user.ageDays, + + // Request data + "endpoint": "/api/orders", + "method": "POST", + "duration_ms": 234, + + // Business context + "order_value": 149.99, + "feature_flags": ["new-checkout", "discount-v2"] +]) +``` + + + + + + + +### Consistent Attribute Naming + +Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. + +**Recommended:** Use `snake_case` for custom attributes to match common conventions. + + + + +```swift +// ❌ Inconsistent naming +["user": "123"] +["userId": "123"] +["user_id": "123"] +["UserID": "123"] + +// ✅ Consistent snake_case +SentrySDK.logger.info(message: "Order processed", attributes: [ + "user_id": "123", + "order_id": "456", + "cart_value": 99.99, + "item_count": 3 +]) +``` + + + + diff --git a/platform-includes/logs/best-practices/dart.mdx b/platform-includes/logs/best-practices/dart.mdx new file mode 100644 index 0000000000000..97fe7d162ce1c --- /dev/null +++ b/platform-includes/logs/best-practices/dart.mdx @@ -0,0 +1,104 @@ + + + + +### Wide Events Over Scattered Logs + +Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. + +This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. + + + + +```dart +// ❌ Scattered thin logs +Sentry.logger.info('Starting checkout'); +Sentry.logger.info('Validating cart'); +Sentry.logger.info('Processing payment'); +Sentry.logger.info('Checkout complete'); + +// ✅ One wide event with full context +Sentry.logger.info('Checkout completed', attributes: { + 'order_id': SentryLogAttribute.string(order.id), + 'user_id': SentryLogAttribute.string(user.id), + 'user_tier': SentryLogAttribute.string(user.subscription), + 'cart_value': SentryLogAttribute.double(cart.total), + 'item_count': SentryLogAttribute.int(cart.items.length), + 'payment_method': SentryLogAttribute.string('stripe'), + 'duration_ms': SentryLogAttribute.int( + DateTime.now().difference(startTime).inMilliseconds), +}); +``` + + + + + + + +### Include Business Context + +Add attributes that help you prioritize and debug: + +- **User context** — tier, account age, lifetime value +- **Transaction data** — order value, item count +- **Feature state** — active feature flags +- **Request metadata** — endpoint, method, duration + +This lets you filter logs by high-value customers or specific features. + + + + +```dart +Sentry.logger.info('API request completed', attributes: { + // User context + 'user_id': SentryLogAttribute.string(user.id), + 'user_tier': SentryLogAttribute.string(user.plan), + 'account_age_days': SentryLogAttribute.int(user.ageDays), + + // Request data + 'endpoint': SentryLogAttribute.string('/api/orders'), + 'method': SentryLogAttribute.string('POST'), + 'duration_ms': SentryLogAttribute.int(234), + + // Business context + 'order_value': SentryLogAttribute.double(149.99), +}); +``` + + + + + + + +### Consistent Attribute Naming + +Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. + +**Recommended:** Use `snake_case` for custom attributes to match Dart conventions. + + + + +```dart +// ❌ Inconsistent naming +{'user': SentryLogAttribute.string('123')} +{'userId': SentryLogAttribute.string('123')} +{'user_id': SentryLogAttribute.string('123')} +{'UserID': SentryLogAttribute.string('123')} + +// ✅ Consistent snake_case +{ + 'user_id': SentryLogAttribute.string('123'), + 'order_id': SentryLogAttribute.string('456'), + 'cart_value': SentryLogAttribute.double(99.99), + 'item_count': SentryLogAttribute.int(3), +} +``` + + + + diff --git a/platform-includes/logs/best-practices/dotnet.mdx b/platform-includes/logs/best-practices/dotnet.mdx new file mode 100644 index 0000000000000..a9110c861b4ed --- /dev/null +++ b/platform-includes/logs/best-practices/dotnet.mdx @@ -0,0 +1,106 @@ + + + + +### Wide Events Over Scattered Logs + +Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. + +This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. + + + + +```csharp +// ❌ Scattered thin logs +SentrySdk.Logger.LogInfo("Starting checkout"); +SentrySdk.Logger.LogInfo("Validating cart"); +SentrySdk.Logger.LogInfo("Processing payment"); +SentrySdk.Logger.LogInfo("Checkout complete"); + +// ✅ One wide event with full context +SentrySdk.Logger.LogInfo(log => +{ + log.SetAttribute("order_id", order.Id); + log.SetAttribute("user_id", user.Id); + log.SetAttribute("user_tier", user.Subscription); + log.SetAttribute("cart_value", cart.Total); + log.SetAttribute("item_count", cart.Items.Count); + log.SetAttribute("payment_method", "stripe"); + log.SetAttribute("duration_ms", stopwatch.ElapsedMilliseconds); +}, "Checkout completed"); +``` + + + + + + + +### Include Business Context + +Add attributes that help you prioritize and debug: + +- **User context** — tier, account age, lifetime value +- **Transaction data** — order value, item count +- **Feature state** — active feature flags +- **Request metadata** — endpoint, method, duration + +This lets you filter logs by high-value customers or specific features. + + + + +```csharp +SentrySdk.Logger.LogInfo(log => +{ + // User context + log.SetAttribute("user_id", user.Id); + log.SetAttribute("user_tier", user.Plan); // "free" | "pro" | "enterprise" + log.SetAttribute("account_age_days", user.AgeDays); + + // Request data + log.SetAttribute("endpoint", "/api/orders"); + log.SetAttribute("method", "POST"); + log.SetAttribute("duration_ms", 234); + + // Business context + log.SetAttribute("order_value", 149.99); +}, "API request completed"); +``` + + + + + + + +### Consistent Attribute Naming + +Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. + +**Recommended:** Use `snake_case` for custom attributes to match common conventions. + + + + +```csharp +// ❌ Inconsistent naming +log.SetAttribute("user", "123"); +log.SetAttribute("userId", "123"); +log.SetAttribute("user_id", "123"); +log.SetAttribute("UserID", "123"); + +// ✅ Consistent snake_case +SentrySdk.Logger.LogInfo(log => +{ + log.SetAttribute("user_id", "123"); + log.SetAttribute("order_id", "456"); + log.SetAttribute("cart_value", 99.99); + log.SetAttribute("item_count", 3); +}, "Order processed"); +``` + + + + diff --git a/platform-includes/logs/best-practices/go.mdx b/platform-includes/logs/best-practices/go.mdx new file mode 100644 index 0000000000000..9d0ee53dd826a --- /dev/null +++ b/platform-includes/logs/best-practices/go.mdx @@ -0,0 +1,103 @@ + + + + +### Wide Events Over Scattered Logs + +Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. + +This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. + + + + +```go +// ❌ Scattered thin logs +logger.Info().Emit("Starting checkout") +logger.Info().Emit("Validating cart") +logger.Info().Emit("Processing payment") +logger.Info().Emit("Checkout complete") + +// ✅ One wide event with full context +logger.Info(). + String("order_id", order.ID). + String("user_id", user.ID). + String("user_tier", user.Subscription). + Float64("cart_value", cart.Total). + Int("item_count", len(cart.Items)). + String("payment_method", "stripe"). + Int64("duration_ms", time.Since(startTime).Milliseconds()). + Emit("Checkout completed") +``` + + + + + + + +### Include Business Context + +Add attributes that help you prioritize and debug: + +- **User context** — tier, account age, lifetime value +- **Transaction data** — order value, item count +- **Feature state** — active feature flags +- **Request metadata** — endpoint, method, duration + +This lets you filter logs by high-value customers or specific features. + + + + +```go +logger.Info(). + // User context + String("user_id", user.ID). + String("user_tier", user.Plan). // "free" | "pro" | "enterprise" + Int("account_age_days", user.AgeDays). + + // Request data + String("endpoint", "/api/orders"). + String("method", "POST"). + Int64("duration_ms", 234). + + // Business context + Float64("order_value", 149.99). + Emit("API request completed") +``` + + + + + + + +### Consistent Attribute Naming + +Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. + +**Recommended:** Use `snake_case` for custom attributes to match common conventions. + + + + +```go +// ❌ Inconsistent naming +logger.Info().String("user", "123").Emit("msg") +logger.Info().String("userId", "123").Emit("msg") +logger.Info().String("user_id", "123").Emit("msg") +logger.Info().String("UserID", "123").Emit("msg") + +// ✅ Consistent snake_case +logger.Info(). + String("user_id", "123"). + String("order_id", "456"). + Float64("cart_value", 99.99). + Int("item_count", 3). + Emit("Order processed") +``` + + + + diff --git a/platform-includes/logs/best-practices/godot.mdx b/platform-includes/logs/best-practices/godot.mdx new file mode 100644 index 0000000000000..6466d64ffd63c --- /dev/null +++ b/platform-includes/logs/best-practices/godot.mdx @@ -0,0 +1,103 @@ + + + + +### Wide Events Over Scattered Logs + +Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. + +This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. + + + + +```gdscript +# ❌ Scattered thin logs +SentrySDK.logger.info("Starting checkout") +SentrySDK.logger.info("Validating cart") +SentrySDK.logger.info("Processing payment") +SentrySDK.logger.info("Checkout complete") + +# ✅ One wide event with full context +SentrySDK.logger.info("Checkout completed", [], { + "order_id": order.id, + "user_id": user.id, + "user_tier": user.subscription, + "cart_value": cart.total, + "item_count": cart.items.size(), + "payment_method": "stripe", + "duration_ms": (Time.get_ticks_msec() - start_time) +}) +``` + + + + + + + +### Include Business Context + +Add attributes that help you prioritize and debug: + +- **User context** — tier, account age, lifetime value +- **Transaction data** — order value, item count +- **Feature state** — active feature flags +- **Game metadata** — scene, level, player state + +This lets you filter logs by high-value customers or specific features. + + + + +```gdscript +SentrySDK.logger.info("Level completed", [], { + # User context + "user_id": user.id, + "user_tier": user.plan, # "free" | "pro" | "enterprise" + "account_age_days": user.age_days, + + # Game context + "current_scene": get_tree().current_scene.scene_file_path, + "level": current_level, + "score": player.score, + + # Business context + "is_premium": user.is_premium, +}) +``` + + + + + + + +### Consistent Attribute Naming + +Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. + +**Recommended:** Use `snake_case` for custom attributes to match GDScript conventions. + + + + +```gdscript +# ❌ Inconsistent naming +{"user": "123"} +{"userId": "123"} +{"user_id": "123"} +{"UserID": "123"} + +# ✅ Consistent snake_case +SentrySDK.logger.info("Order processed", [], { + "user_id": "123", + "order_id": "456", + "cart_value": 99.99, + "item_count": 3 +}) +``` + + + + diff --git a/platform-includes/logs/best-practices/java.mdx b/platform-includes/logs/best-practices/java.mdx new file mode 100644 index 0000000000000..0b001ac8b9795 --- /dev/null +++ b/platform-includes/logs/best-practices/java.mdx @@ -0,0 +1,114 @@ + + + + +### Wide Events Over Scattered Logs + +Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. + +This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. + + + + +```java +// ❌ Scattered thin logs +Sentry.logger().info("Starting checkout"); +Sentry.logger().info("Validating cart"); +Sentry.logger().info("Processing payment"); +Sentry.logger().info("Checkout complete"); + +// ✅ One wide event with full context +Sentry.logger().log( + SentryLogLevel.INFO, + SentryLogParameters.create( + SentryAttributes.of( + SentryAttribute.stringAttribute("order_id", order.getId()), + SentryAttribute.stringAttribute("user_id", user.getId()), + SentryAttribute.stringAttribute("user_tier", user.getSubscription()), + SentryAttribute.doubleAttribute("cart_value", cart.getTotal()), + SentryAttribute.integerAttribute("item_count", cart.getItems().size()), + SentryAttribute.stringAttribute("payment_method", "stripe") + ) + ), + "Checkout completed" +); +``` + + + + + + + +### Include Business Context + +Add attributes that help you prioritize and debug: + +- **User context** — tier, account age, lifetime value +- **Transaction data** — order value, item count +- **Feature state** — active feature flags +- **Request metadata** — endpoint, method, duration + +This lets you filter logs by high-value customers or specific features. + + + + +```java +Sentry.logger().log( + SentryLogLevel.INFO, + SentryLogParameters.create( + SentryAttributes.of( + // User context + SentryAttribute.stringAttribute("user_id", user.getId()), + SentryAttribute.stringAttribute("user_tier", user.getPlan()), + SentryAttribute.integerAttribute("account_age_days", user.getAgeDays()), + + // Request data + SentryAttribute.stringAttribute("endpoint", "/api/orders"), + SentryAttribute.stringAttribute("method", "POST"), + SentryAttribute.integerAttribute("duration_ms", 234), + + // Business context + SentryAttribute.doubleAttribute("order_value", 149.99) + ) + ), + "API request completed" +); +``` + + + + + + + +### Consistent Attribute Naming + +Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. + +**Recommended:** Use `snake_case` for custom attributes to match common conventions. + + + + +```java +// ❌ Inconsistent naming +SentryAttribute.stringAttribute("user", "123") +SentryAttribute.stringAttribute("userId", "123") +SentryAttribute.stringAttribute("user_id", "123") +SentryAttribute.stringAttribute("UserID", "123") + +// ✅ Consistent snake_case +SentryAttributes.of( + SentryAttribute.stringAttribute("user_id", "123"), + SentryAttribute.stringAttribute("order_id", "456"), + SentryAttribute.doubleAttribute("cart_value", 99.99), + SentryAttribute.integerAttribute("item_count", 3) +) +``` + + + + diff --git a/platform-includes/logs/best-practices/javascript.mdx b/platform-includes/logs/best-practices/javascript.mdx new file mode 100644 index 0000000000000..33c2ebd75a949 --- /dev/null +++ b/platform-includes/logs/best-practices/javascript.mdx @@ -0,0 +1,104 @@ + + + + +### Wide Events Over Scattered Logs + +Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. + +This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. + + + + +```javascript +// ❌ Scattered thin logs +Sentry.logger.info("Starting checkout"); +Sentry.logger.info("Validating cart"); +Sentry.logger.info("Processing payment"); +Sentry.logger.info("Checkout complete"); + +// ✅ One wide event with full context +Sentry.logger.info("Checkout completed", { + order_id: order.id, + user_id: user.id, + user_tier: user.subscription, + cart_value: cart.total, + item_count: cart.items.length, + payment_method: "stripe", + duration_ms: Date.now() - startTime, +}); +``` + + + + + + + +### Include Business Context + +Add attributes that help you prioritize and debug: + +- **User context** — tier, account age, lifetime value +- **Transaction data** — order value, item count +- **Feature state** — active feature flags +- **Request metadata** — endpoint, method, duration + +This lets you filter logs by high-value customers or specific features. + + + + +```javascript +Sentry.logger.info("API request completed", { + // User context + user_id: user.id, + user_tier: user.plan, // "free" | "pro" | "enterprise" + account_age_days: user.ageDays, + + // Request data + endpoint: "/api/orders", + method: "POST", + duration_ms: 234, + + // Business context + order_value: 149.99, + feature_flags: ["new-checkout", "discount-v2"], +}); +``` + + + + + + + +### Consistent Attribute Naming + +Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. + +**Recommended:** Use `snake_case` for custom attributes to match common conventions. + + + + +```javascript +// ❌ Inconsistent naming +{ user: "123" } +{ userId: "123" } +{ user_id: "123" } +{ UserID: "123" } + +// ✅ Consistent snake_case +{ + user_id: "123", + order_id: "456", + cart_value: 99.99, + item_count: 3, +} +``` + + + + diff --git a/platform-includes/logs/best-practices/native.mdx b/platform-includes/logs/best-practices/native.mdx new file mode 100644 index 0000000000000..94c129ce6a742 --- /dev/null +++ b/platform-includes/logs/best-practices/native.mdx @@ -0,0 +1,94 @@ + + + + +### Wide Events Over Scattered Logs + +Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. + +This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. + + + + +```c +// ❌ Scattered thin logs +sentry_log_info("Starting checkout"); +sentry_log_info("Validating cart"); +sentry_log_info("Processing payment"); +sentry_log_info("Checkout complete"); + +// ✅ One wide event with full context +sentry_log_info("Checkout completed - order: %s, user: %s, value: %.2f", + order_id, user_id, cart_value); +``` + + + + + + + +### Include Business Context + +Add attributes that help you prioritize and debug: + +- **User context** — tier, account age, lifetime value +- **Transaction data** — order value, item count +- **Feature state** — active feature flags +- **Request metadata** — endpoint, method, duration + +This lets you filter logs by high-value customers or specific features. + + + + +```c +// Include context in formatted messages +sentry_log_info("API request - endpoint: %s, method: %s, user: %s, duration: %dms", + "/api/orders", "POST", user_id, duration_ms); + +// Or use attributes (requires logs_with_attributes option) +sentry_value_t attrs = sentry_value_new_object(); +sentry_value_set_by_key(attrs, "user_id", + sentry_value_new_attribute(sentry_value_new_string(user_id), NULL)); +sentry_value_set_by_key(attrs, "endpoint", + sentry_value_new_attribute(sentry_value_new_string("/api/orders"), NULL)); +sentry_value_set_by_key(attrs, "duration_ms", + sentry_value_new_attribute(sentry_value_new_int64(duration_ms), NULL)); + +sentry_log_info("API request completed", attrs); +``` + + + + + + + +### Consistent Attribute Naming + +Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. + +**Recommended:** Use `snake_case` for custom attributes to match common conventions. + + + + +```c +// ❌ Inconsistent naming +sentry_value_set_by_key(attrs, "user", ...); +sentry_value_set_by_key(attrs, "userId", ...); +sentry_value_set_by_key(attrs, "user_id", ...); +sentry_value_set_by_key(attrs, "UserID", ...); + +// ✅ Consistent snake_case +sentry_value_set_by_key(attrs, "user_id", ...); +sentry_value_set_by_key(attrs, "order_id", ...); +sentry_value_set_by_key(attrs, "cart_value", ...); +sentry_value_set_by_key(attrs, "item_count", ...); +``` + + + + diff --git a/platform-includes/logs/best-practices/php.mdx b/platform-includes/logs/best-practices/php.mdx new file mode 100644 index 0000000000000..2b102b9c81bd9 --- /dev/null +++ b/platform-includes/logs/best-practices/php.mdx @@ -0,0 +1,104 @@ + + + + +### Wide Events Over Scattered Logs + +Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. + +This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. + + + + +```php +// ❌ Scattered thin logs +\Sentry\logger()->info('Starting checkout'); +\Sentry\logger()->info('Validating cart'); +\Sentry\logger()->info('Processing payment'); +\Sentry\logger()->info('Checkout complete'); + +// ✅ One wide event with full context +\Sentry\logger()->info('Checkout completed', attributes: [ + 'order_id' => $order->id, + 'user_id' => $user->id, + 'user_tier' => $user->subscription, + 'cart_value' => $cart->total, + 'item_count' => count($cart->items), + 'payment_method' => 'stripe', + 'duration_ms' => (microtime(true) - $startTime) * 1000, +]); +``` + + + + + + + +### Include Business Context + +Add attributes that help you prioritize and debug: + +- **User context** — tier, account age, lifetime value +- **Transaction data** — order value, item count +- **Feature state** — active feature flags +- **Request metadata** — endpoint, method, duration + +This lets you filter logs by high-value customers or specific features. + + + + +```php +\Sentry\logger()->info('API request completed', attributes: [ + // User context + 'user_id' => $user->id, + 'user_tier' => $user->plan, // "free" | "pro" | "enterprise" + 'account_age_days' => $user->ageDays, + + // Request data + 'endpoint' => '/api/orders', + 'method' => 'POST', + 'duration_ms' => 234, + + // Business context + 'order_value' => 149.99, + 'feature_flags' => ['new-checkout', 'discount-v2'], +]); +``` + + + + + + + +### Consistent Attribute Naming + +Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. + +**Recommended:** Use `snake_case` for custom attributes to match PHP conventions. + + + + +```php +// ❌ Inconsistent naming +['user' => '123'] +['userId' => '123'] +['user_id' => '123'] +['UserID' => '123'] + +// ✅ Consistent snake_case +[ + 'user_id' => '123', + 'order_id' => '456', + 'cart_value' => 99.99, + 'item_count' => 3, +] +``` + + + + diff --git a/platform-includes/logs/best-practices/python.mdx b/platform-includes/logs/best-practices/python.mdx new file mode 100644 index 0000000000000..d7aae98a58d20 --- /dev/null +++ b/platform-includes/logs/best-practices/python.mdx @@ -0,0 +1,110 @@ + + + + +### Wide Events Over Scattered Logs + +Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. + +This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. + + + + +```python +# ❌ Scattered thin logs +sentry_logger.info("Starting checkout") +sentry_logger.info("Validating cart") +sentry_logger.info("Processing payment") +sentry_logger.info("Checkout complete") + +# ✅ One wide event with full context +sentry_logger.info( + "Checkout completed", + attributes={ + "order_id": order.id, + "user_id": user.id, + "user_tier": user.subscription, + "cart_value": cart.total, + "item_count": len(cart.items), + "payment_method": "stripe", + "duration_ms": (time.time() - start_time) * 1000, + } +) +``` + + + + + + + +### Include Business Context + +Add attributes that help you prioritize and debug: + +- **User context** — tier, account age, lifetime value +- **Transaction data** — order value, item count +- **Feature state** — active feature flags +- **Request metadata** — endpoint, method, duration + +This lets you filter logs by high-value customers or specific features. + + + + +```python +sentry_logger.info( + "API request completed", + attributes={ + # User context + "user_id": user.id, + "user_tier": user.plan, # "free" | "pro" | "enterprise" + "account_age_days": user.age_days, + + # Request data + "endpoint": "/api/orders", + "method": "POST", + "duration_ms": 234, + + # Business context + "order_value": 149.99, + "feature_flags": ["new-checkout", "discount-v2"], + } +) +``` + + + + + + + +### Consistent Attribute Naming + +Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. + +**Recommended:** Use `snake_case` for custom attributes to match Python conventions. + + + + +```python +# ❌ Inconsistent naming +{"user": "123"} +{"userId": "123"} +{"user_id": "123"} +{"UserID": "123"} + +# ✅ Consistent snake_case +{ + "user_id": "123", + "order_id": "456", + "cart_value": 99.99, + "item_count": 3, +} +``` + + + + diff --git a/platform-includes/logs/best-practices/react-native.mdx b/platform-includes/logs/best-practices/react-native.mdx new file mode 100644 index 0000000000000..33c2ebd75a949 --- /dev/null +++ b/platform-includes/logs/best-practices/react-native.mdx @@ -0,0 +1,104 @@ + + + + +### Wide Events Over Scattered Logs + +Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. + +This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. + + + + +```javascript +// ❌ Scattered thin logs +Sentry.logger.info("Starting checkout"); +Sentry.logger.info("Validating cart"); +Sentry.logger.info("Processing payment"); +Sentry.logger.info("Checkout complete"); + +// ✅ One wide event with full context +Sentry.logger.info("Checkout completed", { + order_id: order.id, + user_id: user.id, + user_tier: user.subscription, + cart_value: cart.total, + item_count: cart.items.length, + payment_method: "stripe", + duration_ms: Date.now() - startTime, +}); +``` + + + + + + + +### Include Business Context + +Add attributes that help you prioritize and debug: + +- **User context** — tier, account age, lifetime value +- **Transaction data** — order value, item count +- **Feature state** — active feature flags +- **Request metadata** — endpoint, method, duration + +This lets you filter logs by high-value customers or specific features. + + + + +```javascript +Sentry.logger.info("API request completed", { + // User context + user_id: user.id, + user_tier: user.plan, // "free" | "pro" | "enterprise" + account_age_days: user.ageDays, + + // Request data + endpoint: "/api/orders", + method: "POST", + duration_ms: 234, + + // Business context + order_value: 149.99, + feature_flags: ["new-checkout", "discount-v2"], +}); +``` + + + + + + + +### Consistent Attribute Naming + +Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. + +**Recommended:** Use `snake_case` for custom attributes to match common conventions. + + + + +```javascript +// ❌ Inconsistent naming +{ user: "123" } +{ userId: "123" } +{ user_id: "123" } +{ UserID: "123" } + +// ✅ Consistent snake_case +{ + user_id: "123", + order_id: "456", + cart_value: 99.99, + item_count: 3, +} +``` + + + + diff --git a/platform-includes/logs/best-practices/ruby.mdx b/platform-includes/logs/best-practices/ruby.mdx new file mode 100644 index 0000000000000..7d35160aac34a --- /dev/null +++ b/platform-includes/logs/best-practices/ruby.mdx @@ -0,0 +1,104 @@ + + + + +### Wide Events Over Scattered Logs + +Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. + +This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. + + + + +```ruby +# ❌ Scattered thin logs +Sentry.logger.info("Starting checkout") +Sentry.logger.info("Validating cart") +Sentry.logger.info("Processing payment") +Sentry.logger.info("Checkout complete") + +# ✅ One wide event with full context +Sentry.logger.info("Checkout completed", + order_id: order.id, + user_id: user.id, + user_tier: user.subscription, + cart_value: cart.total, + item_count: cart.items.count, + payment_method: "stripe", + duration_ms: ((Time.now - start_time) * 1000).to_i +) +``` + + + + + + + +### Include Business Context + +Add attributes that help you prioritize and debug: + +- **User context** — tier, account age, lifetime value +- **Transaction data** — order value, item count +- **Feature state** — active feature flags +- **Request metadata** — endpoint, method, duration + +This lets you filter logs by high-value customers or specific features. + + + + +```ruby +Sentry.logger.info("API request completed", + # User context + user_id: user.id, + user_tier: user.plan, # "free" | "pro" | "enterprise" + account_age_days: user.age_days, + + # Request data + endpoint: "/api/orders", + method: "POST", + duration_ms: 234, + + # Business context + order_value: 149.99, + feature_flags: ["new-checkout", "discount-v2"] +) +``` + + + + + + + +### Consistent Attribute Naming + +Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. + +**Recommended:** Use `snake_case` for custom attributes to match Ruby conventions. + + + + +```ruby +# ❌ Inconsistent naming +{ user: "123" } +{ userId: "123" } +{ user_id: "123" } +{ UserID: "123" } + +# ✅ Consistent snake_case +{ + user_id: "123", + order_id: "456", + cart_value: 99.99, + item_count: 3 +} +``` + + + + diff --git a/platform-includes/logs/best-practices/rust.mdx b/platform-includes/logs/best-practices/rust.mdx new file mode 100644 index 0000000000000..f41b8574994b4 --- /dev/null +++ b/platform-includes/logs/best-practices/rust.mdx @@ -0,0 +1,106 @@ + + + + +### Wide Events Over Scattered Logs + +Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. + +This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. + + + + +```rust +// ❌ Scattered thin logs +sentry::logger::info!("Starting checkout"); +sentry::logger::info!("Validating cart"); +sentry::logger::info!("Processing payment"); +sentry::logger::info!("Checkout complete"); + +// ✅ One wide event with full context +sentry::logger::info!( + "Checkout completed"; + "order_id" => order.id, + "user_id" => user.id, + "user_tier" => user.subscription, + "cart_value" => cart.total, + "item_count" => cart.items.len(), + "payment_method" => "stripe", + "duration_ms" => start_time.elapsed().as_millis(), +); +``` + + + + + + + +### Include Business Context + +Add attributes that help you prioritize and debug: + +- **User context** — tier, account age, lifetime value +- **Transaction data** — order value, item count +- **Feature state** — active feature flags +- **Request metadata** — endpoint, method, duration + +This lets you filter logs by high-value customers or specific features. + + + + +```rust +sentry::logger::info!( + "API request completed"; + // User context + "user_id" => user.id, + "user_tier" => user.plan, // "free" | "pro" | "enterprise" + "account_age_days" => user.age_days, + + // Request data + "endpoint" => "/api/orders", + "method" => "POST", + "duration_ms" => 234, + + // Business context + "order_value" => 149.99, +); +``` + + + + + + + +### Consistent Attribute Naming + +Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. + +**Recommended:** Use `snake_case` for custom attributes to match Rust conventions. + + + + +```rust +// ❌ Inconsistent naming +"user" => "123" +"userId" => "123" +"user_id" => "123" +"UserID" => "123" + +// ✅ Consistent snake_case +sentry::logger::info!( + "Order processed"; + "user_id" => "123", + "order_id" => "456", + "cart_value" => 99.99, + "item_count" => 3, +); +``` + + + + diff --git a/platform-includes/logs/best-practices/unity.mdx b/platform-includes/logs/best-practices/unity.mdx new file mode 100644 index 0000000000000..91875ca83de8c --- /dev/null +++ b/platform-includes/logs/best-practices/unity.mdx @@ -0,0 +1,105 @@ + + + + +### Wide Events Over Scattered Logs + +Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. + +This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. + + + + +```csharp +// ❌ Scattered thin logs +SentrySdk.Logger.LogInfo("Starting checkout"); +SentrySdk.Logger.LogInfo("Validating cart"); +SentrySdk.Logger.LogInfo("Processing payment"); +SentrySdk.Logger.LogInfo("Checkout complete"); + +// ✅ One wide event with full context +SentrySdk.Logger.LogInfo(log => +{ + log.SetAttribute("order_id", order.Id); + log.SetAttribute("user_id", user.Id); + log.SetAttribute("user_tier", user.Subscription); + log.SetAttribute("cart_value", cart.Total); + log.SetAttribute("item_count", cart.Items.Count); + log.SetAttribute("payment_method", "stripe"); + log.SetAttribute("duration_ms", (Time.realtimeSinceStartup - startTime) * 1000); +}, "Checkout completed"); +``` + + + + + + + +### Include Business Context + +Add attributes that help you prioritize and debug: + +- **User context** — tier, account age, lifetime value +- **Transaction data** — order value, item count +- **Feature state** — active feature flags +- **Request metadata** — endpoint, method, duration + +This lets you filter logs by high-value customers or specific features. + + + + +```csharp +SentrySdk.Logger.LogInfo(log => +{ + // User context + log.SetAttribute("user_id", user.Id); + log.SetAttribute("user_tier", user.Plan); // "free" | "pro" | "enterprise" + log.SetAttribute("account_age_days", user.AgeDays); + + // Game context + log.SetAttribute("scene", SceneManager.GetActiveScene().name); + log.SetAttribute("level", currentLevel); + + // Business context + log.SetAttribute("purchase_value", 149.99f); +}, "In-app purchase completed"); +``` + + + + + + + +### Consistent Attribute Naming + +Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. + +**Recommended:** Use `snake_case` for custom attributes to match common conventions. + + + + +```csharp +// ❌ Inconsistent naming +log.SetAttribute("user", "123"); +log.SetAttribute("userId", "123"); +log.SetAttribute("user_id", "123"); +log.SetAttribute("UserID", "123"); + +// ✅ Consistent snake_case +SentrySdk.Logger.LogInfo(log => +{ + log.SetAttribute("user_id", "123"); + log.SetAttribute("order_id", "456"); + log.SetAttribute("cart_value", 99.99f); + log.SetAttribute("item_count", 3); +}, "Order processed"); +``` + + + + diff --git a/platform-includes/logs/best-practices/unreal.mdx b/platform-includes/logs/best-practices/unreal.mdx new file mode 100644 index 0000000000000..c343a096ebaf3 --- /dev/null +++ b/platform-includes/logs/best-practices/unreal.mdx @@ -0,0 +1,98 @@ + + + + +### Wide Events Over Scattered Logs + +Instead of many thin logs that are hard to correlate, emit one comprehensive log per operation with all relevant context. + +This makes debugging dramatically faster — one query returns everything about a specific order, user, or request. + + + + +```cpp +// ❌ Scattered thin logs +SentrySubsystem->AddLog(TEXT("Starting checkout"), ESentryLevel::Info); +SentrySubsystem->AddLog(TEXT("Validating cart"), ESentryLevel::Info); +SentrySubsystem->AddLog(TEXT("Processing payment"), ESentryLevel::Info); +SentrySubsystem->AddLog(TEXT("Checkout complete"), ESentryLevel::Info); + +// ✅ One wide event with full context +// Use categories and descriptive messages +SentrySubsystem->AddLog( + FString::Printf(TEXT("Checkout completed - Order: %s, User: %s, Value: %.2f"), + *OrderId, *UserId, CartValue), + ESentryLevel::Info, + TEXT("Checkout") +); +``` + + + + + + + +### Include Business Context + +Add attributes that help you prioritize and debug: + +- **User context** — tier, account age, lifetime value +- **Transaction data** — order value, item count +- **Feature state** — active feature flags +- **Game metadata** — level, scene, player state + +Use categories to organize logs and make them easier to search and filter. + + + + +```cpp +// Use categories for different systems +SentrySubsystem->AddLog( + FString::Printf(TEXT("Purchase completed - User: %s, Tier: %s, Value: %.2f"), + *UserId, *UserTier, PurchaseValue), + ESentryLevel::Info, + TEXT("IAP") +); + +SentrySubsystem->AddLog( + FString::Printf(TEXT("Level loaded - Name: %s, LoadTime: %.2fs"), + *LevelName, LoadTime), + ESentryLevel::Info, + TEXT("GameFlow") +); +``` + + + + + + + +### Consistent Attribute Naming + +Pick a naming convention and stick with it across your codebase. Inconsistent names make queries impossible. + +**Recommended:** Use consistent category names and message formats. + + + + +```cpp +// ❌ Inconsistent categories +SentrySubsystem->AddLog(TEXT("..."), ESentryLevel::Info, TEXT("player")); +SentrySubsystem->AddLog(TEXT("..."), ESentryLevel::Info, TEXT("Player")); +SentrySubsystem->AddLog(TEXT("..."), ESentryLevel::Info, TEXT("PLAYER")); +SentrySubsystem->AddLog(TEXT("..."), ESentryLevel::Info, TEXT("PlayerSystem")); + +// ✅ Consistent PascalCase categories +SentrySubsystem->AddLog(TEXT("Player spawned"), ESentryLevel::Info, TEXT("Player")); +SentrySubsystem->AddLog(TEXT("Player died"), ESentryLevel::Warning, TEXT("Player")); +SentrySubsystem->AddLog(TEXT("Player score updated"), ESentryLevel::Debug, TEXT("Player")); +``` + + + +