@ngxtm/devkit 3.4.0 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/rules/README.md +141 -0
- package/rules/dart/best-practices/SKILL.md +23 -0
- package/rules/dart/language/SKILL.md +52 -0
- package/rules/dart/tooling/SKILL.md +43 -0
- package/rules/dotnet/aspnet-core/SKILL.md +92 -0
- package/rules/dotnet/aspnet-core/references/REFERENCE.md +335 -0
- package/rules/dotnet/best-practices/SKILL.md +101 -0
- package/rules/dotnet/best-practices/references/REFERENCE.md +256 -0
- package/rules/dotnet/blazor/SKILL.md +146 -0
- package/rules/dotnet/blazor/references/REFERENCE.md +392 -0
- package/rules/dotnet/language/SKILL.md +82 -0
- package/rules/dotnet/language/references/REFERENCE.md +222 -0
- package/rules/dotnet/patterns.rule.md +388 -0
- package/rules/dotnet/razor-pages/SKILL.md +124 -0
- package/rules/dotnet/razor-pages/references/REFERENCE.md +321 -0
- package/rules/dotnet/security/SKILL.md +89 -0
- package/rules/dotnet/security/references/REFERENCE.md +295 -0
- package/rules/dotnet/tooling/SKILL.md +92 -0
- package/rules/dotnet/tooling/references/REFERENCE.md +300 -0
- package/rules/flutter/auto-route-navigation/SKILL.md +43 -0
- package/rules/flutter/auto-route-navigation/references/REFERENCE.md +19 -0
- package/rules/flutter/auto-route-navigation/references/router-config.md +62 -0
- package/rules/flutter/bloc-state-management/SKILL.md +64 -0
- package/rules/flutter/bloc-state-management/references/REFERENCE.md +20 -0
- package/rules/flutter/bloc-state-management/references/auth-bloc-example.md +52 -0
- package/rules/flutter/bloc-state-management/references/equatable-usage.md +56 -0
- package/rules/flutter/bloc-state-management/references/property-based-state.md +68 -0
- package/rules/flutter/bloc.rule.md +76 -0
- package/rules/flutter/cicd/SKILL.md +48 -0
- package/rules/flutter/cicd/references/advanced-workflow.md +66 -0
- package/rules/flutter/cicd/references/fastlane.md +139 -0
- package/rules/flutter/cicd/references/github-actions.md +59 -0
- package/rules/flutter/dependency-injection/SKILL.md +42 -0
- package/rules/flutter/dependency-injection/references/REFERENCE.md +15 -0
- package/rules/flutter/dependency-injection/references/modules.md +37 -0
- package/rules/flutter/error-handling/SKILL.md +32 -0
- package/rules/flutter/error-handling/references/REFERENCE.md +19 -0
- package/rules/flutter/error-handling/references/error-mapping.md +31 -0
- package/rules/flutter/feature-based-clean-architecture/SKILL.md +46 -0
- package/rules/flutter/feature-based-clean-architecture/references/REFERENCE.md +14 -0
- package/rules/flutter/feature-based-clean-architecture/references/folder-structure.md +36 -0
- package/rules/flutter/getx-navigation/SKILL.md +70 -0
- package/rules/flutter/getx-navigation/references/app-pages.md +40 -0
- package/rules/flutter/getx-navigation/references/middleware-example.md +29 -0
- package/rules/flutter/getx-state-management/SKILL.md +76 -0
- package/rules/flutter/getx-state-management/references/binding-example.md +32 -0
- package/rules/flutter/getx-state-management/references/reactive-vs-simple.md +39 -0
- package/rules/flutter/go-router-navigation/SKILL.md +57 -0
- package/rules/flutter/idiomatic-flutter/SKILL.md +20 -0
- package/rules/flutter/layer-based-clean-architecture/SKILL.md +50 -0
- package/rules/flutter/layer-based-clean-architecture/references/REFERENCE.md +60 -0
- package/rules/flutter/layer-based-clean-architecture/references/repository-mapping.md +50 -0
- package/rules/flutter/localization/SKILL.md +50 -0
- package/rules/flutter/localization/references/REFERENCE.md +48 -0
- package/rules/flutter/localization/references/sheet-loader.md +33 -0
- package/rules/flutter/navigator-v1-navigation/SKILL.md +71 -0
- package/rules/flutter/navigator-v1-navigation/references/on-generate-route.md +48 -0
- package/rules/flutter/performance/SKILL.md +24 -0
- package/rules/flutter/retrofit-networking/SKILL.md +51 -0
- package/rules/flutter/retrofit-networking/references/REFERENCE.md +19 -0
- package/rules/flutter/retrofit-networking/references/token-refresh.md +40 -0
- package/rules/flutter/riverpod-state-management/SKILL.md +53 -0
- package/rules/flutter/riverpod-state-management/references/architecture.md +124 -0
- package/rules/flutter/riverpod-state-management/references/best-practices.md +89 -0
- package/rules/flutter/riverpod-state-management/references/testing.md +73 -0
- package/rules/flutter/riverpod.rule.md +78 -0
- package/rules/flutter/security/SKILL.md +33 -0
- package/rules/flutter/security/references/REFERENCE.md +15 -0
- package/rules/flutter/security/references/network-security.md +28 -0
- package/rules/flutter/testing/SKILL.md +44 -0
- package/rules/flutter/testing/references/REFERENCE.md +21 -0
- package/rules/flutter/testing/references/bloc-testing.md +38 -0
- package/rules/flutter/testing/references/integration-testing.md +128 -0
- package/rules/flutter/testing/references/robot-pattern.md +82 -0
- package/rules/flutter/testing/references/unit-testing.md +130 -0
- package/rules/flutter/testing/references/widget-testing.md +120 -0
- package/rules/flutter/widgets/SKILL.md +37 -0
- package/rules/golang/chi-router/SKILL.md +219 -0
- package/rules/golang/chi-router/references/REFERENCE.md +13 -0
- package/rules/golang/chi-router/references/routing-patterns.md +205 -0
- package/rules/golang/cobra-cli/SKILL.md +227 -0
- package/rules/golang/cobra-cli/references/REFERENCE.md +13 -0
- package/rules/golang/cobra-cli/references/command-patterns.md +224 -0
- package/rules/golang/core/SKILL.md +210 -0
- package/rules/golang/core/references/REFERENCE.md +14 -0
- package/rules/golang/core/references/concurrency-patterns.md +114 -0
- package/rules/golang/core/references/error-handling.md +87 -0
- package/rules/golang/echo-framework/SKILL.md +215 -0
- package/rules/golang/echo-framework/references/REFERENCE.md +14 -0
- package/rules/golang/echo-framework/references/middleware-patterns.md +141 -0
- package/rules/golang/echo-framework/references/routing-patterns.md +140 -0
- package/rules/golang/ent-orm/SKILL.md +239 -0
- package/rules/golang/ent-orm/references/REFERENCE.md +13 -0
- package/rules/golang/ent-orm/references/schema-patterns.md +255 -0
- package/rules/golang/fiber-framework/SKILL.md +196 -0
- package/rules/golang/fiber-framework/references/REFERENCE.md +13 -0
- package/rules/golang/fiber-framework/references/routing-patterns.md +191 -0
- package/rules/golang/gin-framework/SKILL.md +205 -0
- package/rules/golang/gin-framework/references/REFERENCE.md +14 -0
- package/rules/golang/gin-framework/references/middleware-patterns.md +119 -0
- package/rules/golang/gorm-orm/SKILL.md +196 -0
- package/rules/golang/gorm-orm/references/REFERENCE.md +14 -0
- package/rules/golang/gorm-orm/references/model-definitions.md +167 -0
- package/rules/golang/gorm-orm/references/query-patterns.md +161 -0
- package/rules/golang/grpc/SKILL.md +231 -0
- package/rules/golang/grpc/references/REFERENCE.md +13 -0
- package/rules/golang/grpc/references/service-patterns.md +276 -0
- package/rules/golang/testify/SKILL.md +239 -0
- package/rules/golang/testify/references/REFERENCE.md +13 -0
- package/rules/golang/testify/references/assert-patterns.md +170 -0
- package/rules/golang/validator/SKILL.md +234 -0
- package/rules/golang/validator/references/REFERENCE.md +13 -0
- package/rules/golang/validator/references/validation-tags.md +211 -0
- package/rules/golang/viper-config/SKILL.md +244 -0
- package/rules/golang/viper-config/references/REFERENCE.md +13 -0
- package/rules/golang/viper-config/references/config-loading.md +181 -0
- package/rules/golang/wire-di/SKILL.md +243 -0
- package/rules/golang/wire-di/references/REFERENCE.md +13 -0
- package/rules/golang/wire-di/references/provider-patterns.md +193 -0
- package/rules/golang/zap-logging/SKILL.md +203 -0
- package/rules/golang/zap-logging/references/REFERENCE.md +13 -0
- package/rules/golang/zap-logging/references/logger-config.md +165 -0
- package/rules/java/build-gradle/SKILL.md +92 -0
- package/rules/java/build-gradle/references/REFERENCE.md +14 -0
- package/rules/java/build-gradle/references/kotlin-dsl.md +118 -0
- package/rules/java/build-gradle/references/task-configuration.md +132 -0
- package/rules/java/build-maven/SKILL.md +86 -0
- package/rules/java/build-maven/references/REFERENCE.md +14 -0
- package/rules/java/build-maven/references/dependency-management.md +111 -0
- package/rules/java/build-maven/references/lifecycle-phases.md +114 -0
- package/rules/java/graalvm-native/SKILL.md +105 -0
- package/rules/java/graalvm-native/references/REFERENCE.md +12 -0
- package/rules/java/java-collections-streams/SKILL.md +148 -0
- package/rules/java/java-collections-streams/references/REFERENCE.md +15 -0
- package/rules/java/java-collections-streams/references/collectors-patterns.md +178 -0
- package/rules/java/java-collections-streams/references/stream-pipelines.md +165 -0
- package/rules/java/java-concurrency/SKILL.md +187 -0
- package/rules/java/java-concurrency/references/REFERENCE.md +17 -0
- package/rules/java/java-concurrency/references/completable-future.md +165 -0
- package/rules/java/java-concurrency/references/executor-patterns.md +176 -0
- package/rules/java/java-concurrency/references/virtual-threads.md +190 -0
- package/rules/java/java-core-language/SKILL.md +121 -0
- package/rules/java/java-core-language/references/REFERENCE.md +15 -0
- package/rules/java/java-core-language/references/jvm-memory-model.md +160 -0
- package/rules/java/java-core-language/references/modern-java-features.md +168 -0
- package/rules/java/java-project-structure/SKILL.md +195 -0
- package/rules/java/java-project-structure/references/REFERENCE.md +15 -0
- package/rules/java/java-project-structure/references/maven-project-layout.md +199 -0
- package/rules/java/java-project-structure/references/module-system.md +159 -0
- package/rules/java/micronaut-core/SKILL.md +99 -0
- package/rules/java/micronaut-core/references/REFERENCE.md +12 -0
- package/rules/java/micronaut-reactive/SKILL.md +68 -0
- package/rules/java/micronaut-reactive/references/REFERENCE.md +12 -0
- package/rules/java/quarkus-core/SKILL.md +85 -0
- package/rules/java/quarkus-core/references/REFERENCE.md +12 -0
- package/rules/java/quarkus-reactive/SKILL.md +67 -0
- package/rules/java/quarkus-reactive/references/REFERENCE.md +12 -0
- package/rules/java/spring-batch/SKILL.md +102 -0
- package/rules/java/spring-batch/references/REFERENCE.md +12 -0
- package/rules/java/spring-boot-architecture/SKILL.md +206 -0
- package/rules/java/spring-boot-architecture/references/REFERENCE.md +15 -0
- package/rules/java/spring-boot-architecture/references/auto-configuration.md +158 -0
- package/rules/java/spring-boot-architecture/references/configuration-properties.md +202 -0
- package/rules/java/spring-boot-web/SKILL.md +217 -0
- package/rules/java/spring-boot-web/references/REFERENCE.md +17 -0
- package/rules/java/spring-cloud/SKILL.md +109 -0
- package/rules/java/spring-cloud/references/REFERENCE.md +13 -0
- package/rules/java/spring-data-jpa/SKILL.md +241 -0
- package/rules/java/spring-data-jpa/references/REFERENCE.md +16 -0
- package/rules/java/spring-security/SKILL.md +161 -0
- package/rules/java/spring-security/references/REFERENCE.md +16 -0
- package/rules/java/spring-security/references/jwt-auth-flow.md +213 -0
- package/rules/java/testing-junit-mockito/SKILL.md +135 -0
- package/rules/java/testing-junit-mockito/references/REFERENCE.md +15 -0
- package/rules/java/testing-junit-mockito/references/junit5-patterns.md +159 -0
- package/rules/java/testing-junit-mockito/references/mockito-patterns.md +148 -0
- package/rules/java/testing-junit-mockito/references/spring-boot-testing.md +152 -0
- package/rules/javascript/best-practices/SKILL.md +64 -0
- package/rules/javascript/best-practices/references/REFERENCE.md +91 -0
- package/rules/javascript/language/SKILL.md +71 -0
- package/rules/javascript/language/references/REFERENCE.md +106 -0
- package/rules/javascript/tooling/SKILL.md +60 -0
- package/rules/javascript/tooling/references/REFERENCE.md +107 -0
- package/rules/metadata.json +54 -0
- package/rules/nestjs/api-standards/SKILL.md +47 -0
- package/rules/nestjs/api-standards/references/pagination-wrapper.md +87 -0
- package/rules/nestjs/architecture/SKILL.md +68 -0
- package/rules/nestjs/architecture/references/dynamic-module.md +53 -0
- package/rules/nestjs/caching/SKILL.md +51 -0
- package/rules/nestjs/caching/references/REFERENCE.md +13 -0
- package/rules/nestjs/caching/references/cache-patterns.md +183 -0
- package/rules/nestjs/configuration/SKILL.md +41 -0
- package/rules/nestjs/configuration/references/REFERENCE.md +13 -0
- package/rules/nestjs/configuration/references/config-patterns.md +184 -0
- package/rules/nestjs/controllers-services/SKILL.md +63 -0
- package/rules/nestjs/controllers-services/references/REFERENCE.md +14 -0
- package/rules/nestjs/controllers-services/references/controller-patterns.md +119 -0
- package/rules/nestjs/controllers-services/references/service-patterns.md +129 -0
- package/rules/nestjs/database/SKILL.md +102 -0
- package/rules/nestjs/database/references/REFERENCE.md +14 -0
- package/rules/nestjs/database/references/typeorm-patterns.md +156 -0
- package/rules/nestjs/deployment/SKILL.md +36 -0
- package/rules/nestjs/deployment/references/REFERENCE.md +13 -0
- package/rules/nestjs/deployment/references/deployment-patterns.md +140 -0
- package/rules/nestjs/documentation/SKILL.md +64 -0
- package/rules/nestjs/documentation/references/REFERENCE.md +13 -0
- package/rules/nestjs/documentation/references/swagger-patterns.md +139 -0
- package/rules/nestjs/error-handling/SKILL.md +55 -0
- package/rules/nestjs/error-handling/references/REFERENCE.md +13 -0
- package/rules/nestjs/error-handling/references/exception-filters.md +152 -0
- package/rules/nestjs/file-uploads/SKILL.md +35 -0
- package/rules/nestjs/file-uploads/references/REFERENCE.md +13 -0
- package/rules/nestjs/file-uploads/references/upload-patterns.md +125 -0
- package/rules/nestjs/observability/SKILL.md +39 -0
- package/rules/nestjs/observability/references/REFERENCE.md +13 -0
- package/rules/nestjs/observability/references/logging-metrics.md +175 -0
- package/rules/nestjs/performance/SKILL.md +60 -0
- package/rules/nestjs/performance/references/REFERENCE.md +13 -0
- package/rules/nestjs/performance/references/performance-patterns.md +107 -0
- package/rules/nestjs/real-time/SKILL.md +45 -0
- package/rules/nestjs/real-time/references/REFERENCE.md +13 -0
- package/rules/nestjs/real-time/references/websocket-patterns.md +121 -0
- package/rules/nestjs/scheduling/SKILL.md +39 -0
- package/rules/nestjs/scheduling/references/REFERENCE.md +13 -0
- package/rules/nestjs/scheduling/references/scheduling-patterns.md +137 -0
- package/rules/nestjs/search/SKILL.md +41 -0
- package/rules/nestjs/search/references/REFERENCE.md +13 -0
- package/rules/nestjs/search/references/search-patterns.md +137 -0
- package/rules/nestjs/security/SKILL.md +87 -0
- package/rules/nestjs/security/references/REFERENCE.md +14 -0
- package/rules/nestjs/security/references/authentication.md +151 -0
- package/rules/nestjs/testing/SKILL.md +40 -0
- package/rules/nestjs/testing/references/REFERENCE.md +14 -0
- package/rules/nestjs/testing/references/unit-testing.md +179 -0
- package/rules/nestjs/transport/SKILL.md +45 -0
- package/rules/nestjs/transport/references/REFERENCE.md +13 -0
- package/rules/nestjs/transport/references/microservices-patterns.md +170 -0
- package/rules/nextjs/app-router/SKILL.md +46 -0
- package/rules/nextjs/app-router/references/REFERENCE.md +14 -0
- package/rules/nextjs/app-router/references/routing-patterns.md +182 -0
- package/rules/nextjs/architecture/SKILL.md +44 -0
- package/rules/nextjs/architecture/references/fsd-structure.md +77 -0
- package/rules/nextjs/authentication/SKILL.md +29 -0
- package/rules/nextjs/authentication/references/auth-implementation.md +73 -0
- package/rules/nextjs/caching/SKILL.md +66 -0
- package/rules/nextjs/caching/references/REFERENCE.md +13 -0
- package/rules/nextjs/caching/references/cache-strategies.md +168 -0
- package/rules/nextjs/data-access-layer/SKILL.md +33 -0
- package/rules/nextjs/data-access-layer/references/patterns.md +66 -0
- package/rules/nextjs/data-fetching/SKILL.md +59 -0
- package/rules/nextjs/data-fetching/references/REFERENCE.md +13 -0
- package/rules/nextjs/data-fetching/references/fetch-patterns.md +160 -0
- package/rules/nextjs/internationalization/SKILL.md +105 -0
- package/rules/nextjs/internationalization/references/REFERENCE.md +13 -0
- package/rules/nextjs/internationalization/references/i18n-patterns.md +180 -0
- package/rules/nextjs/optimization/SKILL.md +64 -0
- package/rules/nextjs/optimization/references/REFERENCE.md +13 -0
- package/rules/nextjs/optimization/references/optimization-patterns.md +190 -0
- package/rules/nextjs/rendering/SKILL.md +91 -0
- package/rules/nextjs/rendering/references/REFERENCE.md +13 -0
- package/rules/nextjs/rendering/references/rendering-modes.md +163 -0
- package/rules/nextjs/server-actions/SKILL.md +46 -0
- package/rules/nextjs/server-actions/references/REFERENCE.md +13 -0
- package/rules/nextjs/server-actions/references/action-patterns.md +188 -0
- package/rules/nextjs/server-components/SKILL.md +52 -0
- package/rules/nextjs/server-components/references/REFERENCE.md +13 -0
- package/rules/nextjs/server-components/references/component-patterns.md +175 -0
- package/rules/nextjs/state-management/SKILL.md +73 -0
- package/rules/nextjs/state-management/references/REFERENCE.md +13 -0
- package/rules/nextjs/state-management/references/state-patterns.md +218 -0
- package/rules/nextjs/styling/SKILL.md +31 -0
- package/rules/nextjs/styling/references/implementation.md +56 -0
- package/rules/react/component-patterns/SKILL.md +66 -0
- package/rules/react/component-patterns/references/REFERENCE.md +126 -0
- package/rules/react/hooks/SKILL.md +60 -0
- package/rules/react/hooks/references/REFERENCE.md +132 -0
- package/rules/react/hooks.rule.md +79 -0
- package/rules/react/performance/SKILL.md +69 -0
- package/rules/react/performance/references/REFERENCE.md +143 -0
- package/rules/react/security/SKILL.md +46 -0
- package/rules/react/security/references/REFERENCE.md +170 -0
- package/rules/react/state-management/SKILL.md +56 -0
- package/rules/react/state-management/references/REFERENCE.md +137 -0
- package/rules/react/testing/SKILL.md +45 -0
- package/rules/react/testing/references/REFERENCE.md +149 -0
- package/rules/react/tooling/SKILL.md +39 -0
- package/rules/react/typescript/SKILL.md +53 -0
- package/rules/rust/actix-web/SKILL.md +160 -0
- package/rules/rust/actix-web/references/REFERENCE.md +13 -0
- package/rules/rust/actix-web/references/handler-patterns.md +198 -0
- package/rules/rust/async-graphql/SKILL.md +228 -0
- package/rules/rust/async-graphql/references/REFERENCE.md +13 -0
- package/rules/rust/async-graphql/references/schema-patterns.md +215 -0
- package/rules/rust/axum/SKILL.md +161 -0
- package/rules/rust/axum/references/REFERENCE.md +14 -0
- package/rules/rust/axum/references/handler-patterns.md +97 -0
- package/rules/rust/bevy/SKILL.md +206 -0
- package/rules/rust/bevy/references/REFERENCE.md +13 -0
- package/rules/rust/bevy/references/ecs-patterns.md +226 -0
- package/rules/rust/clap/SKILL.md +217 -0
- package/rules/rust/clap/references/REFERENCE.md +13 -0
- package/rules/rust/clap/references/derive-patterns.md +205 -0
- package/rules/rust/core/SKILL.md +154 -0
- package/rules/rust/core/references/REFERENCE.md +14 -0
- package/rules/rust/core/references/error-handling.md +92 -0
- package/rules/rust/diesel-orm/SKILL.md +176 -0
- package/rules/rust/diesel-orm/references/REFERENCE.md +13 -0
- package/rules/rust/diesel-orm/references/schema-patterns.md +206 -0
- package/rules/rust/rocket/SKILL.md +182 -0
- package/rules/rust/rocket/references/REFERENCE.md +13 -0
- package/rules/rust/rocket/references/handler-patterns.md +209 -0
- package/rules/rust/sea-orm/SKILL.md +230 -0
- package/rules/rust/sea-orm/references/REFERENCE.md +13 -0
- package/rules/rust/sea-orm/references/entity-patterns.md +221 -0
- package/rules/rust/serde-serialization/SKILL.md +150 -0
- package/rules/rust/serde-serialization/references/REFERENCE.md +13 -0
- package/rules/rust/serde-serialization/references/serialization-patterns.md +199 -0
- package/rules/rust/sqlx-database/SKILL.md +140 -0
- package/rules/rust/sqlx-database/references/REFERENCE.md +13 -0
- package/rules/rust/sqlx-database/references/query-patterns.md +210 -0
- package/rules/rust/tauri/SKILL.md +180 -0
- package/rules/rust/tauri/references/REFERENCE.md +13 -0
- package/rules/rust/tauri/references/command-patterns.md +209 -0
- package/rules/rust/tokio-runtime/SKILL.md +167 -0
- package/rules/rust/tokio-runtime/references/REFERENCE.md +14 -0
- package/rules/rust/tokio-runtime/references/async-patterns.md +137 -0
- package/rules/rust/tokio-runtime/references/synchronization.md +152 -0
- package/rules/rust/tonic/SKILL.md +231 -0
- package/rules/rust/tonic/references/REFERENCE.md +13 -0
- package/rules/rust/tonic/references/service-patterns.md +213 -0
- package/rules/rust/tracing/SKILL.md +214 -0
- package/rules/rust/tracing/references/REFERENCE.md +13 -0
- package/rules/rust/tracing/references/instrumentation.md +187 -0
- package/rules/typescript/best-practices/SKILL.md +108 -0
- package/rules/typescript/best-practices/references/REFERENCE.md +68 -0
- package/rules/typescript/language/SKILL.md +72 -0
- package/rules/typescript/language/references/REFERENCE.md +67 -0
- package/rules/typescript/patterns.rule.md +85 -0
- package/rules/typescript/security/SKILL.md +59 -0
- package/rules/typescript/security/references/REFERENCE.md +113 -0
- package/rules/typescript/tooling/SKILL.md +52 -0
- package/rules/typescript/tooling/references/REFERENCE.md +110 -0
- package/skills/learn/SKILL.md +476 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# Tonic gRPC Service Patterns
|
|
2
|
+
|
|
3
|
+
## Proto Definition
|
|
4
|
+
|
|
5
|
+
```protobuf
|
|
6
|
+
// proto/user.proto
|
|
7
|
+
syntax = "proto3";
|
|
8
|
+
package user;
|
|
9
|
+
|
|
10
|
+
service UserService {
|
|
11
|
+
rpc GetUser (GetUserRequest) returns (User);
|
|
12
|
+
rpc ListUsers (ListUsersRequest) returns (stream User);
|
|
13
|
+
rpc CreateUsers (stream CreateUserRequest) returns (CreateUsersResponse);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
message User {
|
|
17
|
+
int64 id = 1;
|
|
18
|
+
string name = 2;
|
|
19
|
+
string email = 3;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
message GetUserRequest {
|
|
23
|
+
int64 id = 1;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
message ListUsersRequest {
|
|
27
|
+
int32 page_size = 1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
message CreateUserRequest {
|
|
31
|
+
string name = 1;
|
|
32
|
+
string email = 2;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
message CreateUsersResponse {
|
|
36
|
+
int32 created_count = 1;
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Build Configuration
|
|
41
|
+
|
|
42
|
+
```rust
|
|
43
|
+
// build.rs
|
|
44
|
+
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
45
|
+
tonic_build::compile_protos("proto/user.proto")?;
|
|
46
|
+
Ok(())
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Server Implementation
|
|
51
|
+
|
|
52
|
+
```rust
|
|
53
|
+
use tonic::{transport::Server, Request, Response, Status};
|
|
54
|
+
use user::user_service_server::{UserService, UserServiceServer};
|
|
55
|
+
use user::{User, GetUserRequest, ListUsersRequest, CreateUserRequest, CreateUsersResponse};
|
|
56
|
+
use tokio_stream::wrappers::ReceiverStream;
|
|
57
|
+
|
|
58
|
+
pub mod user {
|
|
59
|
+
tonic::include_proto!("user");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
#[derive(Default)]
|
|
63
|
+
pub struct MyUserService {}
|
|
64
|
+
|
|
65
|
+
#[tonic::async_trait]
|
|
66
|
+
impl UserService for MyUserService {
|
|
67
|
+
// Unary RPC
|
|
68
|
+
async fn get_user(
|
|
69
|
+
&self,
|
|
70
|
+
request: Request<GetUserRequest>,
|
|
71
|
+
) -> Result<Response<User>, Status> {
|
|
72
|
+
let req = request.into_inner();
|
|
73
|
+
|
|
74
|
+
// Simulated lookup
|
|
75
|
+
let user = User {
|
|
76
|
+
id: req.id,
|
|
77
|
+
name: "John".into(),
|
|
78
|
+
email: "john@example.com".into(),
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
Ok(Response::new(user))
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Server streaming
|
|
85
|
+
type ListUsersStream = ReceiverStream<Result<User, Status>>;
|
|
86
|
+
|
|
87
|
+
async fn list_users(
|
|
88
|
+
&self,
|
|
89
|
+
request: Request<ListUsersRequest>,
|
|
90
|
+
) -> Result<Response<Self::ListUsersStream>, Status> {
|
|
91
|
+
let (tx, rx) = tokio::sync::mpsc::channel(4);
|
|
92
|
+
|
|
93
|
+
tokio::spawn(async move {
|
|
94
|
+
for i in 0..10 {
|
|
95
|
+
let user = User {
|
|
96
|
+
id: i,
|
|
97
|
+
name: format!("User {}", i),
|
|
98
|
+
email: format!("user{}@example.com", i),
|
|
99
|
+
};
|
|
100
|
+
tx.send(Ok(user)).await.unwrap();
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
Ok(Response::new(ReceiverStream::new(rx)))
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Client streaming
|
|
108
|
+
async fn create_users(
|
|
109
|
+
&self,
|
|
110
|
+
request: Request<tonic::Streaming<CreateUserRequest>>,
|
|
111
|
+
) -> Result<Response<CreateUsersResponse>, Status> {
|
|
112
|
+
let mut stream = request.into_inner();
|
|
113
|
+
let mut count = 0;
|
|
114
|
+
|
|
115
|
+
while let Some(req) = stream.message().await? {
|
|
116
|
+
println!("Creating user: {}", req.name);
|
|
117
|
+
count += 1;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
Ok(Response::new(CreateUsersResponse { created_count: count }))
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
#[tokio::main]
|
|
125
|
+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
126
|
+
let addr = "[::1]:50051".parse()?;
|
|
127
|
+
let service = MyUserService::default();
|
|
128
|
+
|
|
129
|
+
Server::builder()
|
|
130
|
+
.add_service(UserServiceServer::new(service))
|
|
131
|
+
.serve(addr)
|
|
132
|
+
.await?;
|
|
133
|
+
|
|
134
|
+
Ok(())
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Client Implementation
|
|
139
|
+
|
|
140
|
+
```rust
|
|
141
|
+
use user::user_service_client::UserServiceClient;
|
|
142
|
+
use user::GetUserRequest;
|
|
143
|
+
|
|
144
|
+
#[tokio::main]
|
|
145
|
+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
146
|
+
let mut client = UserServiceClient::connect("http://[::1]:50051").await?;
|
|
147
|
+
|
|
148
|
+
// Unary call
|
|
149
|
+
let request = tonic::Request::new(GetUserRequest { id: 1 });
|
|
150
|
+
let response = client.get_user(request).await?;
|
|
151
|
+
println!("User: {:?}", response.into_inner());
|
|
152
|
+
|
|
153
|
+
// Server streaming
|
|
154
|
+
let request = tonic::Request::new(ListUsersRequest { page_size: 10 });
|
|
155
|
+
let mut stream = client.list_users(request).await?.into_inner();
|
|
156
|
+
|
|
157
|
+
while let Some(user) = stream.message().await? {
|
|
158
|
+
println!("Received: {:?}", user);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
Ok(())
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Interceptors
|
|
166
|
+
|
|
167
|
+
```rust
|
|
168
|
+
use tonic::{Request, Status};
|
|
169
|
+
|
|
170
|
+
fn auth_interceptor(mut req: Request<()>) -> Result<Request<()>, Status> {
|
|
171
|
+
let token = req.metadata()
|
|
172
|
+
.get("authorization")
|
|
173
|
+
.and_then(|t| t.to_str().ok());
|
|
174
|
+
|
|
175
|
+
match token {
|
|
176
|
+
Some(t) if validate_token(t) => Ok(req),
|
|
177
|
+
_ => Err(Status::unauthenticated("Invalid token")),
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Apply to server
|
|
182
|
+
Server::builder()
|
|
183
|
+
.add_service(UserServiceServer::with_interceptor(service, auth_interceptor))
|
|
184
|
+
.serve(addr)
|
|
185
|
+
.await?;
|
|
186
|
+
|
|
187
|
+
// Apply to client
|
|
188
|
+
let channel = Channel::from_static("http://[::1]:50051").connect().await?;
|
|
189
|
+
let client = UserServiceClient::with_interceptor(channel, |mut req: Request<()>| {
|
|
190
|
+
req.metadata_mut().insert("authorization", "Bearer token".parse().unwrap());
|
|
191
|
+
Ok(req)
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Error Handling
|
|
196
|
+
|
|
197
|
+
```rust
|
|
198
|
+
use tonic::Status;
|
|
199
|
+
|
|
200
|
+
async fn get_user(&self, request: Request<GetUserRequest>) -> Result<Response<User>, Status> {
|
|
201
|
+
let id = request.into_inner().id;
|
|
202
|
+
|
|
203
|
+
if id <= 0 {
|
|
204
|
+
return Err(Status::invalid_argument("ID must be positive"));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
match self.db.find_user(id).await {
|
|
208
|
+
Ok(Some(user)) => Ok(Response::new(user)),
|
|
209
|
+
Ok(None) => Err(Status::not_found(format!("User {} not found", id))),
|
|
210
|
+
Err(e) => Err(Status::internal(format!("Database error: {}", e))),
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
```
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Tracing Observability
|
|
3
|
+
description: Structured logging and distributed tracing for Rust.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [rust, tracing, logging, observability]
|
|
6
|
+
triggers:
|
|
7
|
+
files: ['**/main.rs', '**/lib.rs']
|
|
8
|
+
keywords: [tracing, info, debug, span, instrument, subscriber]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Tracing Standards
|
|
12
|
+
|
|
13
|
+
## Setup
|
|
14
|
+
|
|
15
|
+
```rust
|
|
16
|
+
use tracing::Level;
|
|
17
|
+
use tracing_subscriber::{fmt, prelude::*, EnvFilter};
|
|
18
|
+
|
|
19
|
+
fn main() {
|
|
20
|
+
tracing_subscriber::registry()
|
|
21
|
+
.with(fmt::layer())
|
|
22
|
+
.with(EnvFilter::from_default_env()
|
|
23
|
+
.add_directive(Level::INFO.into()))
|
|
24
|
+
.init();
|
|
25
|
+
|
|
26
|
+
tracing::info!("Application started");
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Log Levels
|
|
31
|
+
|
|
32
|
+
```rust
|
|
33
|
+
use tracing::{trace, debug, info, warn, error};
|
|
34
|
+
|
|
35
|
+
fn process() {
|
|
36
|
+
trace!("Very detailed info");
|
|
37
|
+
debug!("Debug information");
|
|
38
|
+
info!("Normal operation");
|
|
39
|
+
warn!("Warning condition");
|
|
40
|
+
error!("Error occurred");
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Structured Fields
|
|
45
|
+
|
|
46
|
+
```rust
|
|
47
|
+
use tracing::{info, warn};
|
|
48
|
+
|
|
49
|
+
fn handle_request(user_id: u64, path: &str) {
|
|
50
|
+
info!(user_id, path, "Processing request");
|
|
51
|
+
|
|
52
|
+
// Named fields
|
|
53
|
+
info!(
|
|
54
|
+
user.id = user_id,
|
|
55
|
+
request.path = path,
|
|
56
|
+
request.method = "GET",
|
|
57
|
+
"Request received"
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// Debug formatting
|
|
61
|
+
let data = vec![1, 2, 3];
|
|
62
|
+
info!(?data, "Data received");
|
|
63
|
+
|
|
64
|
+
// Display formatting
|
|
65
|
+
let error = std::io::Error::new(std::io::ErrorKind::NotFound, "missing");
|
|
66
|
+
warn!(%error, "Operation failed");
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Spans
|
|
71
|
+
|
|
72
|
+
```rust
|
|
73
|
+
use tracing::{span, Level, info_span};
|
|
74
|
+
|
|
75
|
+
fn process_order(order_id: u64) {
|
|
76
|
+
let span = info_span!("process_order", order_id);
|
|
77
|
+
let _guard = span.enter();
|
|
78
|
+
|
|
79
|
+
// All logs within this scope include order_id
|
|
80
|
+
tracing::info!("Starting order processing");
|
|
81
|
+
validate_order();
|
|
82
|
+
charge_payment();
|
|
83
|
+
tracing::info!("Order completed");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Async spans
|
|
87
|
+
async fn fetch_data() {
|
|
88
|
+
let span = info_span!("fetch_data");
|
|
89
|
+
async {
|
|
90
|
+
// async work
|
|
91
|
+
}.instrument(span).await;
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## #[instrument] Macro
|
|
96
|
+
|
|
97
|
+
```rust
|
|
98
|
+
use tracing::instrument;
|
|
99
|
+
|
|
100
|
+
#[instrument]
|
|
101
|
+
fn calculate(x: i32, y: i32) -> i32 {
|
|
102
|
+
x + y
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Skip sensitive fields
|
|
106
|
+
#[instrument(skip(password))]
|
|
107
|
+
fn login(username: &str, password: &str) -> bool {
|
|
108
|
+
true
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Custom span name and level
|
|
112
|
+
#[instrument(name = "db_query", level = "debug")]
|
|
113
|
+
async fn query_database(sql: &str) -> Result<Vec<Row>, Error> {
|
|
114
|
+
// ...
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Add fields
|
|
118
|
+
#[instrument(fields(request_id = %uuid::Uuid::new_v4()))]
|
|
119
|
+
async fn handle_request() {
|
|
120
|
+
// ...
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Skip all, add specific
|
|
124
|
+
#[instrument(skip_all, fields(user_id))]
|
|
125
|
+
fn process_user(user_id: u64, sensitive_data: &str) {
|
|
126
|
+
// ...
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Subscribers
|
|
131
|
+
|
|
132
|
+
```rust
|
|
133
|
+
use tracing_subscriber::{fmt, prelude::*, EnvFilter, Layer};
|
|
134
|
+
|
|
135
|
+
fn setup_tracing() {
|
|
136
|
+
// JSON output for production
|
|
137
|
+
let json_layer = fmt::layer()
|
|
138
|
+
.json()
|
|
139
|
+
.with_target(true)
|
|
140
|
+
.with_current_span(true);
|
|
141
|
+
|
|
142
|
+
// Pretty output for development
|
|
143
|
+
let pretty_layer = fmt::layer()
|
|
144
|
+
.pretty()
|
|
145
|
+
.with_file(true)
|
|
146
|
+
.with_line_number(true);
|
|
147
|
+
|
|
148
|
+
// Filter by RUST_LOG env var
|
|
149
|
+
let filter = EnvFilter::try_from_default_env()
|
|
150
|
+
.unwrap_or_else(|_| EnvFilter::new("info"));
|
|
151
|
+
|
|
152
|
+
tracing_subscriber::registry()
|
|
153
|
+
.with(filter)
|
|
154
|
+
.with(if cfg!(debug_assertions) {
|
|
155
|
+
pretty_layer.boxed()
|
|
156
|
+
} else {
|
|
157
|
+
json_layer.boxed()
|
|
158
|
+
})
|
|
159
|
+
.init();
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## OpenTelemetry Integration
|
|
164
|
+
|
|
165
|
+
```rust
|
|
166
|
+
use opentelemetry::sdk::trace::TracerProvider;
|
|
167
|
+
use tracing_opentelemetry::OpenTelemetryLayer;
|
|
168
|
+
|
|
169
|
+
fn setup_otel() {
|
|
170
|
+
let provider = TracerProvider::builder()
|
|
171
|
+
.with_simple_exporter(opentelemetry_jaeger::new_agent_pipeline())
|
|
172
|
+
.build();
|
|
173
|
+
|
|
174
|
+
let tracer = provider.tracer("my-service");
|
|
175
|
+
|
|
176
|
+
tracing_subscriber::registry()
|
|
177
|
+
.with(tracing_subscriber::fmt::layer())
|
|
178
|
+
.with(OpenTelemetryLayer::new(tracer))
|
|
179
|
+
.init();
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Error Handling
|
|
184
|
+
|
|
185
|
+
```rust
|
|
186
|
+
use tracing::{error, instrument};
|
|
187
|
+
|
|
188
|
+
#[instrument(err)]
|
|
189
|
+
fn fallible_operation() -> Result<(), Error> {
|
|
190
|
+
// Automatically logs error if Err is returned
|
|
191
|
+
Err(Error::new("something failed"))
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// With error level
|
|
195
|
+
#[instrument(err(level = Level::WARN))]
|
|
196
|
+
fn maybe_warn() -> Result<(), Error> {
|
|
197
|
+
// ...
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Manual error logging
|
|
201
|
+
fn handle_error() {
|
|
202
|
+
if let Err(e) = operation() {
|
|
203
|
+
error!(error = %e, "Operation failed");
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Best Practices
|
|
209
|
+
|
|
210
|
+
1. **Structured logging**: Use fields, not string interpolation
|
|
211
|
+
2. **Span context**: Wrap related operations in spans
|
|
212
|
+
3. **Skip sensitive**: Use `skip` for passwords, tokens
|
|
213
|
+
4. **Env filter**: Configure via `RUST_LOG` env var
|
|
214
|
+
5. **Async**: Use `.instrument(span)` for async code
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Rust Tracing References
|
|
2
|
+
|
|
3
|
+
## References
|
|
4
|
+
|
|
5
|
+
- [**Instrumentation**](instrumentation.md) - Spans, events, subscribers
|
|
6
|
+
|
|
7
|
+
## Quick Checks
|
|
8
|
+
|
|
9
|
+
- [ ] Use #[instrument] for automatic spans
|
|
10
|
+
- [ ] Structured fields for context
|
|
11
|
+
- [ ] Appropriate log levels
|
|
12
|
+
- [ ] Subscriber configuration
|
|
13
|
+
- [ ] Span relationships for request tracing
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# Tracing Instrumentation
|
|
2
|
+
|
|
3
|
+
## Basic Setup
|
|
4
|
+
|
|
5
|
+
```rust
|
|
6
|
+
use tracing::{info, warn, error, debug, trace, span, Level};
|
|
7
|
+
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
|
8
|
+
|
|
9
|
+
fn main() {
|
|
10
|
+
// Simple setup
|
|
11
|
+
tracing_subscriber::fmt::init();
|
|
12
|
+
|
|
13
|
+
// Or with layers
|
|
14
|
+
tracing_subscriber::registry()
|
|
15
|
+
.with(tracing_subscriber::fmt::layer())
|
|
16
|
+
.with(tracing_subscriber::EnvFilter::from_default_env())
|
|
17
|
+
.init();
|
|
18
|
+
|
|
19
|
+
info!("Application started");
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Events (Logs)
|
|
24
|
+
|
|
25
|
+
```rust
|
|
26
|
+
use tracing::{info, warn, error, debug, trace};
|
|
27
|
+
|
|
28
|
+
fn process_request(request_id: &str, user_id: u64) {
|
|
29
|
+
// Simple message
|
|
30
|
+
info!("Processing request");
|
|
31
|
+
|
|
32
|
+
// With structured fields
|
|
33
|
+
info!(request_id, user_id, "Processing request");
|
|
34
|
+
|
|
35
|
+
// Named fields
|
|
36
|
+
info!(
|
|
37
|
+
request_id = %request_id,
|
|
38
|
+
user_id = user_id,
|
|
39
|
+
action = "process",
|
|
40
|
+
"Handling user request"
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
// Display vs Debug formatting
|
|
44
|
+
info!(user = %user, "Using Display"); // %
|
|
45
|
+
info!(user = ?user, "Using Debug"); // ?
|
|
46
|
+
|
|
47
|
+
// Error with source
|
|
48
|
+
if let Err(e) = do_something() {
|
|
49
|
+
error!(error = ?e, "Operation failed");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Spans
|
|
55
|
+
|
|
56
|
+
```rust
|
|
57
|
+
use tracing::{span, Level, Instrument};
|
|
58
|
+
|
|
59
|
+
async fn handle_request(request_id: String) {
|
|
60
|
+
// Create span
|
|
61
|
+
let span = span!(Level::INFO, "handle_request", %request_id);
|
|
62
|
+
let _guard = span.enter(); // Auto-exits when dropped
|
|
63
|
+
|
|
64
|
+
info!("Starting request processing");
|
|
65
|
+
|
|
66
|
+
// Nested span
|
|
67
|
+
{
|
|
68
|
+
let db_span = span!(Level::DEBUG, "database_query");
|
|
69
|
+
let _guard = db_span.enter();
|
|
70
|
+
query_database().await;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
info!("Request completed");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Async with instrument
|
|
77
|
+
async fn process() {
|
|
78
|
+
do_work()
|
|
79
|
+
.instrument(span!(Level::INFO, "do_work"))
|
|
80
|
+
.await;
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Instrument Attribute
|
|
85
|
+
|
|
86
|
+
```rust
|
|
87
|
+
use tracing::instrument;
|
|
88
|
+
|
|
89
|
+
#[instrument]
|
|
90
|
+
fn simple_function(x: i32) -> i32 {
|
|
91
|
+
x * 2
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
#[instrument(
|
|
95
|
+
name = "process_user",
|
|
96
|
+
level = "info",
|
|
97
|
+
skip(password), // Don't log sensitive data
|
|
98
|
+
fields(user_id = %user.id),
|
|
99
|
+
err, // Log errors
|
|
100
|
+
ret, // Log return value
|
|
101
|
+
)]
|
|
102
|
+
async fn process_user(user: &User, password: &str) -> Result<(), Error> {
|
|
103
|
+
info!("Processing user");
|
|
104
|
+
Ok(())
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
#[instrument(skip_all, fields(request_id = %request.id))]
|
|
108
|
+
async fn handle(request: Request) -> Response {
|
|
109
|
+
// Implementation
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Custom Subscriber
|
|
114
|
+
|
|
115
|
+
```rust
|
|
116
|
+
use tracing_subscriber::{
|
|
117
|
+
fmt,
|
|
118
|
+
layer::SubscriberExt,
|
|
119
|
+
util::SubscriberInitExt,
|
|
120
|
+
EnvFilter,
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
fn setup_tracing() {
|
|
124
|
+
let fmt_layer = fmt::layer()
|
|
125
|
+
.with_target(true)
|
|
126
|
+
.with_thread_ids(true)
|
|
127
|
+
.with_file(true)
|
|
128
|
+
.with_line_number(true)
|
|
129
|
+
.json(); // JSON output
|
|
130
|
+
|
|
131
|
+
let filter_layer = EnvFilter::try_from_default_env()
|
|
132
|
+
.unwrap_or_else(|_| EnvFilter::new("info"));
|
|
133
|
+
|
|
134
|
+
tracing_subscriber::registry()
|
|
135
|
+
.with(filter_layer)
|
|
136
|
+
.with(fmt_layer)
|
|
137
|
+
.init();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Set level via RUST_LOG env var:
|
|
141
|
+
// RUST_LOG=debug
|
|
142
|
+
// RUST_LOG=my_crate=debug,other_crate=warn
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Integration with Axum
|
|
146
|
+
|
|
147
|
+
```rust
|
|
148
|
+
use axum::{Router, routing::get};
|
|
149
|
+
use tower_http::trace::TraceLayer;
|
|
150
|
+
use tracing::info_span;
|
|
151
|
+
|
|
152
|
+
fn app() -> Router {
|
|
153
|
+
Router::new()
|
|
154
|
+
.route("/", get(handler))
|
|
155
|
+
.layer(
|
|
156
|
+
TraceLayer::new_for_http()
|
|
157
|
+
.make_span_with(|request: &Request<_>| {
|
|
158
|
+
info_span!(
|
|
159
|
+
"http_request",
|
|
160
|
+
method = %request.method(),
|
|
161
|
+
uri = %request.uri(),
|
|
162
|
+
request_id = %uuid::Uuid::new_v4(),
|
|
163
|
+
)
|
|
164
|
+
})
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## OpenTelemetry Integration
|
|
170
|
+
|
|
171
|
+
```rust
|
|
172
|
+
use tracing_subscriber::layer::SubscriberExt;
|
|
173
|
+
use tracing_opentelemetry::OpenTelemetryLayer;
|
|
174
|
+
use opentelemetry::sdk::trace::TracerProvider;
|
|
175
|
+
|
|
176
|
+
fn setup_otel() {
|
|
177
|
+
let tracer = TracerProvider::builder()
|
|
178
|
+
.with_simple_exporter(opentelemetry_jaeger::new_agent_pipeline().build_simple()?)
|
|
179
|
+
.build()
|
|
180
|
+
.tracer("my-service");
|
|
181
|
+
|
|
182
|
+
tracing_subscriber::registry()
|
|
183
|
+
.with(tracing_subscriber::fmt::layer())
|
|
184
|
+
.with(OpenTelemetryLayer::new(tracer))
|
|
185
|
+
.init();
|
|
186
|
+
}
|
|
187
|
+
```
|