### Domain Migration Redirect Example (Go) Source: https://github.com/salt-indonesia/salt-pkg/blob/main/httpmanager/README.md A complete example demonstrating how to handle domain migration by redirecting all traffic from an old domain to a new domain using a permanent redirect. ```Go import ( "log" "net/http" "github.com/salt-indonesia/httpmanager" "github.com/salt-indonesia/logmanager" ) // func main() { // server := httpmanager.NewServer(logmanager.NewApplication()) // server.EnableCORS([]string{"*"}, nil, nil, false) // // Redirect all old domain traffic to new domain // migrationHandler := httpmanager.NewRedirectHandler(http.MethodGet, func(c *httpmanager.Context) { // oldPath := c.Request.URL.Path // c.RedirectPermanent("https://newdomain.com" + oldPath) // }) // server.GET("/old-api/{path:.*}", migrationHandler.WithMiddleware()) // // log.Panic(server.Start()) // } ``` -------------------------------- ### Install httpmanager Go Module Source: https://github.com/salt-indonesia/salt-pkg/blob/main/httpmanager/README.md Installs the httpmanager Go module using the go get command. This is the first step to include the library in your Go project. ```Bash go get github.com/yourusername/httpmanager ``` -------------------------------- ### Install Salt Package Modules (Go) Source: https://github.com/salt-indonesia/salt-pkg/blob/main/README.md Installs individual modules from the salt-pkg repository using Go modules. This command fetches and installs the specified client, HTTP, or log manager packages. ```Bash # Install Client Manager go get github.com/SALT-Indonesia/salt-pkg/clientmanager # Install HTTP Manager go get github.com/SALT-Indonesia/salt-pkg/httpmanager # Install Log Manager go get github.com/SALT-Indonesia/salt-pkg/logmanager ``` -------------------------------- ### Go: Migration Guide for LogManager Methods Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Presents a migration guide showing the transition from deprecated logmanager methods (e.g., LogInfoWithContext) to the recommended context-based methods (e.g., InfoWithContext). ```go // Old way (deprecated but still works) logmanager.LogInfoWithContext(ctx, "User created", fields) logmanager.LogErrorWithContext(ctx, err) // New way (recommended) logmanager.InfoWithContext(ctx, "User created", fields) logmanager.ErrorWithContext(ctx, err) logmanager.DebugWithContext(ctx, "Debug info", fields) ``` -------------------------------- ### Build and Test Go Modules Source: https://github.com/salt-indonesia/salt-pkg/blob/main/CLAUDE.md Standard Go tooling commands for building, testing, and generating coverage reports for all modules in the repository. Includes commands for testing specific modules and building example applications. ```Bash # Build all modules go build ./... # Test all modules go test ./... # Test specific module go test ./clientmanager/... go test ./httpmanager/... go test ./logmanager/... # Run tests with coverage go test -cover ./... # Build examples go build ./examples/... ``` -------------------------------- ### Shell: Install SaltPkg Log Manager Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Command to install the SaltPkg Log Manager library using Go modules. ```shell go get -u github.com/SALT-Indonesia/salt-pkg/logmanager ``` -------------------------------- ### Subscribing to Events with RabbitMQ in Go Source: https://github.com/salt-indonesia/salt-pkg/blob/main/eventmanager/README.md Provides an example of subscribing to RabbitMQ topics using the Salt Event Manager. It outlines required environment variables like RABBITMQ_URL and others for connection configuration. The code includes a message handler function and the subscription setup. ```Go type message struct { // your struct your your incoming messages Title string `json:"title"` Description string `json:"description"` } func handle(m message) error { // an example for handlers log.Println(m) return nil } // you need to run it directly on your main func main() { eventmanager.Subscribe(context.Background(), "myservice", "mytopic", []eventmanager.Handler[message]{handle}) } ``` -------------------------------- ### Integrate SaltPkg with Echo Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Shows how to integrate SaltPkg's logging middleware with an Echo web framework application. This example includes setting the service name, applying the middleware, and handling a GET request with custom log messages. ```go import ( "github.com/labstack/echo/v4" lm "github.com/SALT-Indonesia/salt-pkg/logmanager" "github.com/SALT-Indonesia/salt-pkg/logmanager/lmecho" ) func main() { app := logmanager.NewApplication( logmanager.WithService("api-service"), ) e := echo.New() e.Use(lmecho.Middleware(app)) e.GET("/api/health", handleHealth) e.Logger.Fatal(e.Start(":8080")) } func handleHealth(c echo.Context) error { ctx := c.Request().Context() // Log custom message logmanager.LogErrorWithContext(ctx, nil) // Will log with trace ID return c.JSON(200, map[string]string{ "status": "healthy", }) } ``` -------------------------------- ### Go: Complete Data Masking Example Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Presents a comprehensive example of data masking in Go, combining recursive masking for 'token' and 'password', partial masking for 'apiKey', hiding 'secret', and pattern matching for 'creditcard'. ```go app := logmanager.NewApplication( logmanager.WithMaskingConfig([]logmanager.MaskingConfig{ // Recursive masking - masks all tokens at any level { JSONPath: "$..token", Type: logmanager.FullMask, }, // Recursive masking - masks all passwords anywhere { JSONPath: "$..password", Type: logmanager.FullMask, }, // Partial masking for API keys (show first 4, last 4 chars) { JSONPath: "$..apiKey", Type: logmanager.PartialMask, ShowFirst: 4, ShowLast: 4, }, // Hide sensitive secrets completely { JSONPath: "$.secret", Type: logmanager.HideMask, }, // Field pattern matching (case-insensitive) { FieldPattern: "creditcard", // Matches creditCard, credit_card, CREDITCARD Type: logmanager.PartialMask, ShowFirst: 4, ShowLast: 4, }, }), ) ``` -------------------------------- ### Create and Run a Basic HTTP Server in Go Source: https://github.com/salt-indonesia/salt-pkg/blob/main/httpmanager/README.md Demonstrates how to create a new HTTP server, define request and response structures, register a handler for POST requests to '/hello', and start the server. It uses type-safe handlers for JSON processing. ```Go package main import ( "context" "httpserver" "log" "net/http" ) // HelloRequest Define request and response types type HelloRequest struct { Name string `json:"name"` } type HelloResponse struct { Message string `json:"message"` } func main() { // Create a new server with default options server := httpmanager.NewServer() // Create and register a handler helloHandler := httpmanager.NewHandler(http.MethodPost, func(ctx context.Context, req *HelloRequest) (*HelloResponse, error) { return &HelloResponse{ Message: "Hello, " + req.Name + "!", }, nil }) // Register the handler with a route server.Handle("/hello", helloHandler) // Start the server (blocks until server stops) log.Panic(server.Start()) } ``` -------------------------------- ### Go: Call with URL Parameters Source: https://github.com/salt-indonesia/salt-pkg/blob/main/clientmanager/README.md Demonstrates making an HTTP GET request with URL query parameters using the client manager. It specifies limit, skip, and select parameters for fetching products. ```Go res, err := clientmanager.Call[Response]( context.Background(), "https://dummyjson.com/products", clientmanager.WithURLValues(url.Values{ "limit": {"10"}, "skip": {"10"}, "select": {"title,price"}, }), ) if err != nil { log.Panic(err) } ``` -------------------------------- ### Integrate SaltPkg with Gin Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Demonstrates how to integrate SaltPkg's logging middleware with a Gin web framework application. This example includes setting the service name, trace ID key, applying the middleware, and handling a POST request with automatic request/response logging and field masking. ```go import ( "github.com/gin-gonic/gin" lm "github.com/SALT-Indonesia/salt-pkg/logmanager" "github.com/SALT-Indonesia/salt-pkg/logmanager/lmgin" ) func main() { app := logmanager.NewApplication( logmanager.WithService("api-service"), logmanager.WithTraceIDKey("X-Request-Id"), ) router := gin.New() router.Use(lmgin.Middleware(app)) router.POST("/api/orders", createOrder) router.Run(":8080") } func createOrder(c *gin.Context) { ctx := c.Request.Context() transaction := logmanager.FromContext(ctx) // Automatic request/response logging // Request body with masked fields var req struct { UserID string `json:"user_id"` CreditCard string `json:"credit_card"` // Will be masked Amount float64 `json:"amount"` } c.BindJSON(&req) // Process order... c.JSON(201, gin.H{ "order_id": "ORD-12345", "status": "created", }) } ``` -------------------------------- ### HTTP Request Log Example Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md An example of a typical HTTP request log output in JSON format. It includes service information, trace ID, request method, URL, status, latency, request payload, and response payload. ```json { "service": "user-service", "trace_id": "550e8400-e29b-41d4-a716-446655440000", "type": "http", "method": "POST", "url": "/api/users", "status": 201, "latency": 145, "request": { "name": "John Doe", "email": "john@example.com", "password": "*******" }, "response": { "id": "usr_123", "created_at": "2024-01-15T10:30:00Z" }, "level": "info", "time": "2024-01-15T10:30:00+07:00" } ``` -------------------------------- ### HTTP Server Core Components in Go Source: https://github.com/salt-indonesia/salt-pkg/blob/main/httpmanager/README.md Shows the basic usage of the Server struct for routing and lifecycle management. It includes creating a server, handling requests to a path, and starting the server. ```Go server := httpmanager.NewServer() server.Handle("/path", myHandler) server.Start() // Blocks until server stops ``` -------------------------------- ### Integrate SaltPkg with Gorilla Mux Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Provides a complete example of integrating SaltPkg's logging middleware with a Gorilla Mux router. It includes setting the service name, applying the middleware, and demonstrating a request handler that tracks database operations. ```go import ( "net/http" "github.com/gorilla/mux" lm "github.com/SALT-Indonesia/salt-pkg/logmanager" "github.com/SALT-Indonesia/salt-pkg/logmanager/lmgorilla" ) func main() { app := logmanager.NewApplication( logmanager.WithService("api-service"), ) router := mux.NewRouter() router.Use(lmgorilla.Middleware(app)) router.HandleFunc("/api/users", handleUsers).Methods("GET") http.ListenAndServe(":8080", router) } func handleUsers(w http.ResponseWriter, r *http.Request) { ctx := r.Context() transaction := logmanager.FromContext(ctx) // Track database operation ctx, dbSegment := transaction.StartDatabaseSegment( "fetch-users", logmanager.DatabaseSegment{ Query: "SELECT * FROM users WHERE active = $1" } ) defer dbSegment.End() // Perform query... w.WriteHeader(http.StatusOK) w.Write([]byte(`{"users": []}`)) } ``` -------------------------------- ### Configure HTTP Server Options in Go Source: https://github.com/salt-indonesia/salt-pkg/blob/main/httpmanager/README.md Provides examples of configuring server options such as listening address and read/write timeouts using functional options pattern in Go. ```Go server := httpmanager.NewServer( httpmanager.WithAddr(":3000"), httpmanager.WithReadTimeout(15 * time.Second), httpmanager.WithWriteTimeout(15 * time.Second), ) ``` -------------------------------- ### Database Segment Log Example Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md An example of a JSON log for a database segment. This log details database operations, including service, trace ID, segment name, engine, operation type, SQL query, and latency. ```json { "service": "user-service", "trace_id": "550e8400-e29b-41d4-a716-446655440000", "type": "database", "name": "create-user", "engine": "postgresql", "operation": "INSERT", "query": "INSERT INTO users (name, email) VALUES ($1, $2)", "latency": 15, "level": "info", "time": "2024-01-15T10:30:00+07:00" } ``` -------------------------------- ### API Segment Log Example Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md An example of a JSON log for an API segment. This log captures details about external API calls, including the service, trace ID, API name, method, URL, status, latency, request, and response. ```json { "service": "user-service", "trace_id": "550e8400-e29b-41d4-a716-446655440000", "type": "api", "name": "payment-gateway", "method": "POST", "url": "https://api.payment.com/charge", "status": 200, "latency": 523, "request": { "amount": 100, "currency": "USD" }, "response": { "transaction_id": "TXN_123", "status": "success" }, "level": "info", "time": "2024-01-15T10:30:01+07:00" } ``` -------------------------------- ### JSON: Example Input for Data Masking Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Provides a sample JSON input structure used to demonstrate the data masking capabilities of the SaltPkg log manager. It includes various fields and nesting levels to test different masking configurations. ```json { "user": "john", "token": "rootToken123", "systemToken": "sysToken456", "credentials": { "password": "userPass789", "apiKey": "sk-1234567890abcdef", "nested": { "token": "deepToken012" } }, "users": [ {"name": "alice", "token": "aliceToken345", "password": "alicePass678"} ], "secret": "topSecret", "creditCard": "1234567890123456" } ``` -------------------------------- ### Conditional Redirects based on User Agent (Go) Source: https://github.com/salt-indonesia/salt-pkg/blob/main/httpmanager/README.md Provides an example of implementing conditional redirects based on the 'User-Agent' header. This allows serving different content or redirecting to different domains for mobile vs. desktop users. ```Go import ( "log" "strings" "net/http" "github.com/salt-indonesia/httpmanager" "github.com/salt-indonesia/logmanager" ) // func main() { // server := httpmanager.NewServer(logmanager.NewApplication()) // server.EnableCORS([]string{"*"}, nil, nil, false) // // Conditional redirect based on user agent // mobileRedirectHandler := httpmanager.NewRedirectHandler(http.MethodGet, func(c *httpmanager.Context) { // userAgent := c.GetHeader("User-Agent") // // if strings.Contains(strings.ToLower(userAgent), "mobile") // c.RedirectToURL("https://m.example.com" + c.Request.URL.Path) // else // c.RedirectToURL("https://www.example.com" + c.Request.URL.Path) // } // }) // server.GET("/", mobileRedirectHandler.WithMiddleware()) // // log.Panic(server.Start()) // } ``` -------------------------------- ### Go: Handle File Uploads Source: https://github.com/salt-indonesia/salt-pkg/blob/main/httpmanager/README.md Provides a Go code example for handling file uploads using multipart form data. It shows how to create an upload handler, specify a save directory, process uploaded files and form data, and set options like maximum file size and middleware. ```Go // Create an upload handler uploadHandler := httpmanager.NewUploadHandler( http.MethodPost, "./uploads", // Directory where files will be saved func(ctx context.Context, files map[string][]*httpmanager.UploadedFile, form map[string][]string) (interface{}, error) { // Process uploaded files for fieldName, uploadedFiles := range files { for _, file := range uploadedFiles { // Access file metadata fmt.Printf("Field: %s, File: %s, Size: %d, Type: %s, Saved at: %s\n", fieldName, file.Filename, file.Size, file.ContentType, file.SavedPath) } } // Access form values name := "" if values, ok := form["name"]; ok && len(values) > 0 { name = values[0] } // Return a response return map[string]string{ "status": "success", "message": "Files uploaded successfully", }, nil }, ) // Optionally set maximum file size (default is 10MB) uploadHandler.WithMaxFileSize(20 << 20) // 20MB // Add middleware if needed uploadHandler.Use(authMiddleware) // Register the handler server.Handle("/upload", uploadHandler.WithMiddleware()) ``` -------------------------------- ### HTTP Client Authorizations Source: https://github.com/salt-indonesia/salt-pkg/blob/main/clientmanager/README.md Provides examples for different authorization methods supported by the HTTP client manager, including Basic, Bearer, API Key, JWT, Hawk, AWS Signature, and TSEL ESB. ```Go AuthBasic("user123", "pass123") AuthBearer("pass123") AuthAPIKey("foo", "bar", false) AuthJWT("secret", jwt.SigningMethodHS256, AuthJWTClaims{}) AuthHawk("id", "key", nil) AuthAWS(AWSParameters{}) AuthESB("user123", "pass123") ``` -------------------------------- ### HTML: File Upload Form Source: https://github.com/salt-indonesia/salt-pkg/blob/main/httpmanager/README.md An example of an HTML form designed to work with the file upload handler. It includes fields for text input and file selection, supporting multiple file uploads. ```HTML
``` -------------------------------- ### Go: Access HTTP Headers Source: https://github.com/salt-indonesia/salt-pkg/blob/main/httpmanager/README.md Demonstrates how to retrieve specific HTTP headers or all headers from a request context using the httpmanager package. It shows how to get header values by key and access all headers as an http.Header object. ```Go handlerFunc := func(ctx context.Context, req *UserRequest) (*UserResponse, error) { // Get a specific header value requestID := httpmanager.GetHeader(ctx, "X-Request-ID") // Get all headers headers := httpmanager.GetHeaders(ctx) // Access specific headers from the header collection contentType := headers.Get("Content-Type") authorization := headers.Get("Authorization") // Process request with headers... return &UserResponse{ ID: "user-123", Username: req.Username, Status: "active", RequestID: requestID, }, nil } // Create and register the handler userHandler := httpmanager.NewHandler(http.MethodGet, handlerFunc) server.Handle("/users", userHandler) ``` -------------------------------- ### Go: HTTP Method Shortcuts for Path Parameters Source: https://github.com/salt-indonesia/salt-pkg/blob/main/httpmanager/README.md Illustrates the use of convenient HTTP method shortcuts provided by the SaltPkg module for registering handlers that utilize path parameters. These shortcuts simplify the process of defining routes with dynamic segments. ```Go // HTTP method shortcuts with path parameter support server.GET("/user/{id}", getUserHandler) server.POST("/user/{id}", createUserHandler) server.PUT("/user/{id}", updateUserHandler) server.DELETE("/user/{id}", deleteUserHandler) server.PATCH("/user/{id}", patchUserHandler) ``` -------------------------------- ### Application Configuration with Options Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/docs/ARCHITECTURE.md Demonstrates how to initialize a SaltPkg application with various configuration options. This includes setting the service name, enabling debug mode, specifying the trace ID key, configuring data masking rules using JSONPath, and adding custom tags for environment and version. ```Go app := lm.NewApplication( lm.WithService("my-service"), lm.WithDebug(true), lm.WithTraceIDKey("X-Request-Id"), lm.WithMaskingConfig([]lm.MaskingConfig{ {JSONPath: "$.password", Type: lm.FullMask}, {JSONPath: "$.credit_card", Type: lm.PartialMask}, }), lm.WithTags(map[string]string{ "environment": "production", "version": "1.0.0", }), ) ``` -------------------------------- ### Go: Path Parameter Patterns with Gorilla Mux Syntax Source: https://github.com/salt-indonesia/salt-pkg/blob/main/httpmanager/README.md Shows how to define path parameter patterns using the Gorilla Mux syntax, including basic parameters, multiple parameters, and parameters with regular expression constraints for validation. It also covers wildcard parameters. ```Go // Basic path parameter server.GET("/user/{id}", handler) // Multiple path parameters server.GET("/user/{id}/profile/{section}", handler) // Path parameter with regex pattern (numeric only) server.GET("/user/{id:[0-9]+}", handler) // Path parameter with regex pattern (alphanumeric) server.GET("/user/{id:[a-zA-Z0-9]+}", handler) // Wildcard path parameter (captures remaining path) server.GET("/files/{path:.+}", handler) ``` -------------------------------- ### Go: Log Informational Messages with Context Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Illustrates logging informational messages using InfoWithContext, including basic logging and logging with additional fields for context. ```go func processUserLogin(ctx context.Context, userID string) error { // Basic info logging with trace ID logmanager.InfoWithContext(ctx, "User login attempt started") // Info logging with additional fields fields := map[string]string{ "user_id": userID, "session_id": "session-abc123", "action": "login", } logmanager.InfoWithContext(ctx, "User authenticated successfully", fields) return nil } ``` -------------------------------- ### gRPC Server and Client Interceptors Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Demonstrates how to set up gRPC server and client interceptors using the logmanager and lmgrpc packages for distributed tracing. ```Go import ( "google.golang.org/grpc" lm "github.com/SALT-Indonesia/salt-pkg/logmanager" "github.com/SALT-Indonesia/salt-pkg/logmanager/lmgrpc" ) func main() { app := logmanager.NewApplication( logmanager.WithService("grpc-service"), logmanager.WithTraceIDKey("X-Trace-Id"), ) // Server setup server := grpc.NewServer( grpc.UnaryInterceptor(lmgrpc.UnaryServerInterceptor(app)), grpc.StreamInterceptor(lmgrpc.StreamServerInterceptor(app)), ) // Client setup conn, _ := grpc.Dial("localhost:50051", grpc.WithUnaryInterceptor(lmgrpc.UnaryClientInterceptor(app)), grpc.WithStreamInterceptor(lmgrpc.StreamClientInterceptor(app)), ) } ``` -------------------------------- ### Shell: Set APP_ENV Environment Variable Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Examples of setting the APP_ENV environment variable in the shell to control LogManager's behavior. ```shell # Set via environment variable export APP_ENV=production export APP_ENV=development export APP_ENV=staging ``` -------------------------------- ### Context-Based Redirects (Go) Source: https://github.com/salt-indonesia/salt-pkg/blob/main/httpmanager/README.md Demonstrates context-based redirects using the `Context` type, offering Gin-like redirect methods. This allows for more convenient redirect handling within a request context. ```Go import ( "net/http" "github.com/salt-indonesia/httpmanager" ) // Using RedirectHandler for context-based redirects // redirectHandler := httpmanager.NewRedirectHandler(http.MethodGet, func(c *httpmanager.Context) { // // Redirect with custom status code // c.Redirect(http.StatusFound, "http://example.com") // // // Or use convenience methods // c.RedirectToURL("http://example.com") // 302 Found // c.RedirectPermanent("http://example.com") // 301 Moved Permanently // }) // server.Handle("/old-path", redirectHandler.WithMiddleware()) ``` -------------------------------- ### Run Static Analysis (Go) Source: https://github.com/salt-indonesia/salt-pkg/blob/main/GEMINI.md Performs static analysis checks on the Go project using 'go vet'. This command helps identify potential issues and should be executed from the project's root directory. ```Bash go vet ./... ``` -------------------------------- ### Go Workspace Management Source: https://github.com/salt-indonesia/salt-pkg/blob/main/CLAUDE.md Commands for managing Go workspaces, including syncing dependencies, adding new modules, and downloading necessary packages. Essential for maintaining local development environments. ```Bash # Sync workspace dependencies go work sync # Add new module to workspace go work use ./new-module # Download dependencies go mod download ``` -------------------------------- ### Go: Make Simple HTTP POST Request Source: https://github.com/salt-indonesia/salt-pkg/blob/main/clientmanager/README.md Demonstrates a basic HTTP POST request using the client manager. It sends a JSON request body and prints the response status, body, and success status. Requires the 'context' and 'net/http' packages. ```Go package main import ( "context" "fmt" "log" "net/http" "salt-indonesia/salt-pkg/clientmanager" ) type Request struct { Title string `json:"title"` Price float64 `json:"price"` } type Response struct { ID uint64 `json:"id"` } func main() { req := &Request{ Title: "My Product", Price: 123.45, } res, err := clientmanager.Call[Response]( context.Background(), "https://httpbin.org/post", clientmanager.WithRequestBody(req), clientmanager.WithMethod(http.MethodPost), ) if err != nil { log.Fatal(err) } fmt.Println("HTTP Status:", res.StatusCode) fmt.Println("Response Struct:", res.Body) fmt.Println("Raw Body:", string(res.Raw)) fmt.Println("Success:", res.IsSuccess()) } ``` -------------------------------- ### Go: Array Element Masking with JSONPath Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Provides examples of masking fields within array elements using JSONPath in Go. It demonstrates how to mask 'password' fields in all objects within an array and 'token' fields in specific array elements. ```go logmanager.WithMaskingConfig([]logmanager.MaskingConfig{ { JSONPath: "$[*].password", // Matches: [{"user": "alice", "password": "secret1"}] Type: logmanager.FullMask, }, { JSONPath: "$.users[*].token", // Matches: {"users": [{"token": "abc123"}]} Type: logmanager.FullMask, }, }) ``` -------------------------------- ### Logger Initialization and Configuration Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/docs/ARCHITECTURE.md Shows how to initialize and configure the SaltPkg logger. Options include enabling debug logging, setting the log file path, configuring maximum log file size, the number of backup log files, and the retention period for log files. ```Go logger := lm.InitLogger( lm.WithLoggerDebug(true), lm.WithLoggerFile("app.log"), lm.WithLoggerMaxSize(100), // MB lm.WithLoggerMaxBackups(3), lm.WithLoggerMaxAge(7), // days ) ``` -------------------------------- ### JSON: Example Output After Data Masking Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Shows the expected JSON output after applying the data masking configurations. Sensitive fields like tokens, passwords, API keys, secrets, and credit card numbers are masked according to the defined rules. ```json { "user": "john", "token": "*************", "systemToken": "***********", "credentials": { "password": "***********", "apiKey": "sk-1********cdef", "nested": { "token": "*************" } }, "users": [ {"name": "alice", "token": "*************", "password": "************"} ], "secret": "*", "creditCard": "1234********3456" } ``` -------------------------------- ### Dynamic Redirects with Path Parameters (Go) Source: https://github.com/salt-indonesia/salt-pkg/blob/main/httpmanager/README.md Shows how to create dynamic redirects using path parameters. The `RedirectHandler` can extract parameters from the URL path and query string to construct the redirect URL. ```Go import ( "fmt" "net/http" "github.com/salt-indonesia/httpmanager" ) // Redirect handler with path parameters // redirectHandler := httpmanager.NewRedirectHandler(http.MethodGet, func(c *httpmanager.Context) { // // Get path parameters // pathParams := c.GetPathParams() // userID := pathParams.Get("id") // // // Get query parameters // queryParams := c.GetQueryParams() // section := queryParams.Get("section") // // // Build redirect URL // redirectURL := fmt.Sprintf("https://newdomain.com/users/%s", userID) // if section != "" // redirectURL += "?section=" + section // } // // c.RedirectPermanent(redirectURL) // }) // Register with path parameter // server.GET("/old-user/{id}", redirectHandler.WithMiddleware()) ``` -------------------------------- ### Go: Nested Object Field Masking with JSONPath Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Illustrates masking fields within nested JSON objects using JSONPath in Go. This example shows how to target fields like 'password' inside a 'user' object and 'token' within a 'credentials' object. ```go logmanager.WithMaskingConfig([]logmanager.MaskingConfig{ { JSONPath: "$.user.password", // Matches: {"user": {"password": "secret"}} Type: logmanager.FullMask, }, { JSONPath: "$.credentials.token", // Matches: {"credentials": {"token": "abc123"}} Type: logmanager.FullMask, }, }) ``` -------------------------------- ### Resty Client Integration with Tracing Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Shows how to integrate the Resty HTTP client with SaltPkg's logmanager using lmresty.NewTxn to create transactions from responses. ```Go import ( "context" "github.com/go-resty/resty/v2" "github.com/SALT-Indonesia/salt-pkg/logmanager" "github.com/SALT-Indonesia/salt-pkg/logmanager/integrations/lmresty" ) func callWithResty(ctx context.Context) error { client := resty.New() // Make the request with context that contains transaction resp, err := client.R(). SetContext(ctx). SetBody(map[string]string{"key": "value"}). Post("https://api.example.com/endpoint") if err != nil { return err } // Create a transaction record from response txn := lmresty.NewTxn(resp) if txn != nil { defer txn.End() } return nil } ``` -------------------------------- ### Kafka Producer and Consumer Integration Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Illustrates how to use SaltPkg for tracing Kafka producer and consumer operations with Sarama, including adding trace IDs to message headers. ```Go import ( "github.com/IBM/sarama" "github.com/SALT-Indonesia/salt-pkg/logmanager" ) // Producer func produceMessage(app *logmanager.Application, producer sarama.SyncProducer) { // Start transaction for message txn := app.Start("kafka-produce", "producer", logmanager.TxnTypeOther) defer txn.End() // Create message with trace ID in headers msg := &sarama.ProducerMessage{ Topic: "my-topic", Value: sarama.StringEncoder("message content"), Headers: []sarama.RecordHeader{ {Key: []byte("trace-id"), Value: []byte(txn.TraceID())}, }, } partition, offset, err := producer.SendMessage(msg) if err != nil { txn.NoticeError(err) return } // Transaction automatically logs on End() } // Consumer func consumeMessage(app *logmanager.Application, message *sarama.ConsumerMessage) { // Start transaction for consumed message txn := app.Start("kafka-consume", "consumer", logmanager.TxnTypeConsumer) defer txn.End() // Extract trace ID from headers if available for _, header := range message.Headers { if string(header.Key) == "trace-id" { // Use existing trace ID for distributed tracing break } } // Process message err := processMessage(message.Value) if err != nil { txn.NoticeError(err) return } // Transaction automatically logs on End() } ``` -------------------------------- ### Run All Tests (Go) Source: https://github.com/salt-indonesia/salt-pkg/blob/main/GEMINI.md Executes all tests within the Go monorepo project. This command should be run from the project's root directory. ```Bash go test ./... ``` -------------------------------- ### Configure Custom Tags for Logging Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Demonstrates how to initialize a new application with custom tags for log categorization and filtering. These tags help in organizing and searching logs based on specific attributes like environment, region, or version. ```go app := logmanager.NewApplication( logmanager.WithTags(map[string]string{ "environment": "production", "region": "us-east-1", "version": "1.2.0", }), ) ``` -------------------------------- ### Go: Process Data with Custom Operation Tracking Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Demonstrates tracking custom operations like 'data-processing' using logmanager.StartOtherSegment and logmanager.StartOtherSegmentWithContext. It includes passing context and extra data for detailed logging. ```go import ( "context" "github.com/SALT-Indonesia/salt-pkg/logmanager" ) func processData(ctx context.Context, data []byte) error { transaction := logmanager.FromContext(ctx) // Track custom operation with additional data segment := logmanager.StartOtherSegment(transaction, logmanager.OtherSegment{ Name: "data-processing", Extra: map[string]interface{}{ "input_size": len(data), "type": "batch", }, }) defer segment.End() // Process data... result, err := transform(data) if err != nil { return err } // Custom processing completed successfully return nil } // Alternative using context-based method func processDataWithContext(ctx context.Context, data []byte) error { // Track custom operation using context segment := logmanager.StartOtherSegmentWithContext(ctx, logmanager.OtherSegment{ Name: "data-processing-v2", Extra: map[string]interface{}{ "input_size": len(data), "type": "batch", }, }) defer segment.End() // Process data... result, err := transform(data) if err != nil { return err } return nil } ``` -------------------------------- ### Redirect Handler with Query Parameters (Go) Source: https://github.com/salt-indonesia/salt-pkg/blob/main/httpmanager/README.md Illustrates creating a `RedirectHandler` that dynamically determines the target URL from query parameters. It includes middleware support for adding custom logic like authentication or logging. ```Go import ( "net/http" "github.com/salt-indonesia/httpmanager" "github.com/salt-indonesia/logmanager" ) // Create a redirect handler // redirectHandler := httpmanager.NewRedirectHandler(http.MethodGet, func(c *httpmanager.Context) { // // Access query parameters // targetURL := c.GetQueryParams().Get("redirect_to") // if targetURL == "" // targetURL = "http://default-example.com" // } // // // Redirect to the target URL // c.RedirectToURL(targetURL) // }) // Add middleware if needed // redirectHandler.Use(authMiddleware, loggingMiddleware) // Register with the server // server.GET("/redirect", redirectHandler.WithMiddleware()) ``` -------------------------------- ### Database Operation Segment Tracking Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Demonstrates how to track database operations like querying user data using logmanager.StartDatabaseSegment for detailed tracing. ```Go import ( "context" "database/sql" "github.com/SALT-Indonesia/salt-pkg/logmanager" ) func getUserByID(ctx context.Context, userID string, db *sql.DB) (*User, error) { transaction := logmanager.FromContext(ctx) // Start database segment segment := logmanager.StartDatabaseSegment(transaction, logmanager.DatabaseSegment{ Name: "get-user", Table: "users", Query: "SELECT * FROM users WHERE id = $1", Host: "localhost", // database host }) defer segment.End() // Execute query var user User err := db.QueryRowContext(ctx, "SELECT * FROM users WHERE id = $1", userID).Scan(&user.ID, &user.Name, &user.Email) if err != nil { return nil, err } return &user, nil } ``` -------------------------------- ### RabbitMQ Consumer Wrapper Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Shows how to wrap a RabbitMQ consumer function using lmrabbitmq.WrapConsumer to integrate with the logmanager for tracing. ```Go import ( amqp "github.com/rabbitmq/amqp091-go" lm "github.com/SALT-Indonesia/salt-pkg/logmanager" "github.com/SALT-Indonesia/salt-pkg/logmanager/lmrabbitmq" ) func processMessage(app *logmanager.Application) func(amqp.Delivery) error { return lmrabbitmq.WrapConsumer(app, func(msg amqp.Delivery) error { ctx := context.Background() // Transaction automatically created with correlation ID transaction := logmanager.FromContext(ctx) // Process message... return nil }) } ``` -------------------------------- ### Go: Initialize Log Manager with Environment Configuration Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Demonstrates initializing LogManager with automatic environment detection via the APP_ENV variable or manual setting. It shows how debug mode is affected by the environment. ```go // Automatic environment detection from APP_ENV variable // If APP_ENV=production, debug mode is automatically disabled // If APP_ENV=development or not set, debug mode is enabled by defaultapp := logmanager.NewApplication( logmanager.WithService("your-service-name"), ) // Manual environment setting - overrides APP_ENV app := logmanager.NewApplication( logmanager.WithService("your-service-name"), logmanager.WithEnvironment("production"), // debug automatically disabled ) // Override debug mode even in production (useful for troubleshooting) app := logmanager.NewApplication( logmanager.WithEnvironment("production"), logmanager.WithDebug(), // explicitly enable debug in production ) ``` -------------------------------- ### Go: Initialize Log Manager with Basic Configuration Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Initializes the LogManager with a specified service name and enables debug mode. ```go // Create application with service name app := logmanager.NewApplication( logmanager.WithService("your-service-name"), logmanager.WithDebug(), // Enable debug mode (disable in production) ) ``` -------------------------------- ### Go: Mocking CourierService for Order Use Case Testing Source: https://github.com/salt-indonesia/salt-pkg/blob/main/clientmanager/README.md This Go code demonstrates how to create a mock implementation of the `CourierService` interface. This mock is designed to be used in tests for the `OrderUseCase`, allowing developers to isolate and test the use case logic without relying on actual courier services. It includes the `OrderUseCase` struct, the `CourierService` interface, and a `gojekCourierService` implementation for context. ```go type OrderUseCase struct { courierService CourierService } func (u OrderUseCase) Pay(ctx context.Context, order Order) error { // ... if err := u.courierService.Send(ctx, order); err != nil { return err } // ... return nil } type CourierService interface { Send(context.Context, Order) error } type gojekCourierService struct { host string } func (s gojekCourierService) Send(ctx context.Context, order Order) error { // ... if _, err := clientmanager.Call[any]( context.Background(), fmt.Sprintf("%s/send", s.host), clientmanager.WithRequestBody(toRequest(Order)), clientmanager.WithMethod(http.MethodPost), ); err != nil { return err } // ... return nil } type CourierServiceMock struct { mock.Mock } func (m CourierServiceMock) Send(ctx context.Context, order Order) error { args := m.Called(ctx, order) return args.Error(0) } ``` -------------------------------- ### Go: Call with Proxy Source: https://github.com/salt-indonesia/salt-pkg/blob/main/clientmanager/README.md Shows how to configure and use an HTTP proxy with the client manager. It involves creating a proxy instance and then using a new client manager instance to make the proxied request. ```Go proxy, err := clientmanager.WithProxy("http://localhost:8080") // create the proxy first if err != nil { log.Panic(err) } clientManager := clientmanager.New[string]() // we create a new client manager to create a different HTTP client res, err := clientManager.Call[string]( // call the `Call` method from the `clientManager` instead of the global context.Background(), "https://dummyjson.com/", proxy, // then put your proxy ) if err != nil { log.Panic(err) } ``` -------------------------------- ### Go: Initialize Log Manager with Gin Middleware Source: https://github.com/salt-indonesia/salt-pkg/blob/main/logmanager/README.md Demonstrates how to initialize the LogManager with service name, debug mode, and comprehensive data masking (tokens, passwords, API keys). It then integrates this with Gin middleware for automatic logging in a web service. ```go package main import ( "github.com/gin-gonic/gin" "github.com/SALT-Indonesia/salt-pkg/logmanager" "github.com/SALT-Indonesia/salt-pkg/logmanager/integrations/lmgin" ) func main() { // Configure LogManager with comprehensive masking app := logmanager.NewApplication( logmanager.WithService("user-service"), logmanager.WithDebug(), logmanager.WithMaskingConfig([]logmanager.MaskingConfig{ // Recursive masking - masks any field containing "token" anywhere {JSONPath: "$..token", Type: logmanager.FullMask}, // Recursive masking - masks any field containing "password" anywhere {JSONPath: "$..password", Type: logmanager.FullMask}, // Partial masking for API keys (show first/last 4 chars) {JSONPath: "$..apiKey", Type: logmanager.PartialMask, ShowFirst: 4, ShowLast: 4}, }), ) // Setup Gin with automatic logging router := gin.New() router.Use(lmgin.Middleware(app)) router.POST("/users", createUser) router.Run(":8080") } func createUser(c *gin.Context) { c.JSON(201, gin.H{"id": "123", "status": "created"}) } ``` -------------------------------- ### Configure SSL with Go Server Source: https://github.com/salt-indonesia/salt-pkg/blob/main/httpmanager/README.md Shows how to enable HTTPS for a Go server using the httpmanager module. It covers configuring SSL with certificate and key files, or directly with string data for certificates and keys. ```Go server := httpmanager.NewServer( httpmanager.WithSSL(true), httpmanager.WithCertFile("server.crt"), httpmanager.WithKeyFile("server.key"), ) ``` ```Go server := httpmanager.NewServer( httpmanager.WithSSL(true), httpmanager.WithCertData(certString), httpmanager.WithKeyData(keyString), ) ```