### Install go.yaml.in/yaml/v3 Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/go.yaml.in/yaml/v3/README.md Use 'go get' to install the v3 of the YAML package for Go. ```bash go get go.yaml.in/yaml/v3 ``` -------------------------------- ### Install and Run Blackbox CLI Source: https://context7.com/cloudfoundry/blackbox/llms.txt Install the Blackbox command-line utility using `go install` and run it with a configuration file. Blackbox monitors specified directories and handles shutdown signals gracefully. ```bash # Install blackbox go install code.cloudfoundry.org/blackbox/cmd/blackbox@latest # Run with configuration file blackbox -config /etc/blackbox/config.yml # Example directory structure being monitored: # /var/log/apps/ # ├── webapp/ # │ ├── access.log -> tagged as "webapp" (or "webapp/access.log" if log_filename: true) # │ └── error.log -> tagged as "webapp" (or "webapp/error.log" if log_filename: true) # ├── api-service/ # │ └── app.log -> tagged as "api-service" # └── worker/ # ├── main.log -> tagged as "worker" # └── debug.log -> excluded if exclude_file_pattern: "*.debug.log" ``` -------------------------------- ### Install Blackbox using Go Source: https://github.com/cloudfoundry/blackbox/blob/main/README.md Install the Blackbox tool using the go get command. This command fetches and installs the latest version of the blackbox executable. ```bash go get -u code.cloudfoundry.org/blackbox/cmd/blackbox ``` -------------------------------- ### Run fsnotify command line example Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/fsnotify/fsnotify/README.md Executes the example utility provided in the repository. ```bash % go run ./cmd/fsnotify ``` -------------------------------- ### Install nxadm/tail Library Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/nxadm/tail/README.md Command to install the nxadm/tail library using Go modules. ```Shell go get github.com/nxadm/tail/... ``` -------------------------------- ### Log Directory Structure Example Source: https://github.com/cloudfoundry/blackbox/blob/main/README.md Example directory structure for log files that Blackbox will monitor. Subdirectories are used to group logs, and new lines are tagged based on these directories. ```text /path/to/log-dir |-- app1 | |-- stdout.log | `-- stderr.log `-- app2 |-- foo.log `-- bar.log ``` -------------------------------- ### Example RFC 5424 Message Generated by Blackbox Source: https://context7.com/cloudfoundry/blackbox/llms.txt Illustrates the structure of an RFC 5424 compliant syslog message generated by Blackbox, including priority, version, timestamp, hostname, app-name, proc-id, structured data, and the message content. ```go // Example RFC 5424 message generated by Blackbox: // <14>1 2024-01-15T10:30:45.123456Z my-hostname my-app rs2 - [cfApp@47450 deployment="cf-prod"] Application started // Message components: // - Priority: <14> (User facility + Info severity) // - Version: 1 // - Timestamp: RFC 3339 format with microseconds (UTC) // - Hostname: from config.Hostname // - App-Name: from subdirectory name (max 48 chars, ASCII 33-126 only) // - Proc-ID: "rs2" (hardcoded) // - Structured Data: optional, from config // - Message: the actual log line content // For TCP/TLS transport, messages are prefixed with length: // "234 <14>1 2024-01-15T10:30:45.123456Z..." // For UDP transport, messages are sent without length prefix // and truncated to 1024 bytes maximum ``` -------------------------------- ### Convert Format String to Structured Log Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/go-logr/logr/README.md Example of converting a Kubernetes klog format string log to a structured logger call with key-value pairs. Use this pattern when migrating from format string logging. ```go logger.Error(err, "client returned an error", "code", responseCode) ``` ```go logger.V(4).Info("got a retry-after response when requesting url", "attempt", retries, "after seconds", seconds, "url", url) ``` -------------------------------- ### Secure TLS Syslog Configuration with Structured Data Source: https://context7.com/cloudfoundry/blackbox/llms.txt Configure Blackbox for secure TLS syslog transport, including structured data for enhanced log context. This setup requires specifying the CA certificate path and enables RFC 3339 timestamp format. ```yaml hostname: prod-server-01 use_rfc3339: true max_message_size: 65535 structured_data_id: cfApp@47450 structured_data_map: deployment: cf-prod organization: my-org space: production syslog: destination: transport: tls address: logs.example.com:6514 ca: /var/vcap/jobs/blackbox/certs/ca.crt max_retries: 5 source_dir: /var/vcap/sys/log log_filename: false ``` -------------------------------- ### Create and Follow a Log File Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/nxadm/tail/README.md Demonstrates how to create a tail instance for a log file, enabling follow mode and automatic reopening on rotation. This is useful for real-time log monitoring. ```Go // Create a tail t, err := tail.TailFile( "/var/log/nginx.log", tail.Config{Follow: true, ReOpen: true}) if err != nil { panic(err) } // Print the text of each received line for line := range t.Lines { fmt.Println(line.Text) } ``` -------------------------------- ### Initialize and use fsnotify watcher Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/fsnotify/fsnotify/README.md Demonstrates creating a watcher, handling events and errors in a goroutine, and adding a directory to watch. ```go package main import ( "log" "github.com/fsnotify/fsnotify" ) func main() { // Create new watcher. watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } defer watcher.Close() // Start listening for events. go func() { for { select { case event, ok := <-watcher.Events: if !ok { return } log.Println("event:", event) if event.Has(fsnotify.Write) { log.Println("modified file:", event.Name) } case err, ok := <-watcher.Errors: if !ok { return } log.Println("error:", err) } } }() // Add a path. err = watcher.Add("/tmp") if err != nil { log.Fatal(err) } // Block main goroutine forever. <-make(chan struct{}) } ``` -------------------------------- ### Initialize the root logger Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/go-logr/logr/README.md Create a root logger instance early in the application lifecycle using a specific logging implementation. ```go func main() { // ... other setup code ... // Create the "root" logger. We have chosen the "logimpl" implementation, // which takes some initial parameters and returns a logr.Logger. logger := logimpl.New(param1, param2) // ... other setup code ... ``` -------------------------------- ### Load the Slim-Sprig library Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/go-task/slim-sprig/v3/README.md The FuncMap must be registered with the template object before parsing any template files. ```go import ( "html/template" "github.com/go-task/slim-sprig" ) // This example illustrates that the FuncMap *must* be set before the // templates themselves are loaded. tpl := template.Must( template.New("base").Funcs(sprig.FuncMap()).ParseGlob("*.html") ) ``` -------------------------------- ### Check Version Against Constraints Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/Masterminds/semver/v3/README.md Parses a constraint string and a version string, then evaluates if the version satisfies the constraint. ```go c, err := semver.NewConstraint(">= 1.2.3") if err != nil { // Handle constraint not being parsable. } v, err := semver.NewVersion("1.3") if err != nil { // Handle version not being parsable. } // Check if the version meets the constraints. The variable a will be true. a := c.Check(v) ``` -------------------------------- ### Run Blackbox Source: https://github.com/cloudfoundry/blackbox/blob/main/README.md Execute the blackbox command with a configuration file. Ensure the config.yml file is correctly formatted according to the schema. ```bash blackbox -config config.yml ``` -------------------------------- ### Define Ginkgo Specs Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/onsi/ginkgo/v2/README.md Use Describe, Context, and It blocks to structure test suites. Requires importing Ginkgo and Gomega packages. ```go import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ... ) var _ = Describe("Checking books out of the library", Label("library"), func() { var library *libraries.Library var book *books.Book var valjean *users.User BeforeEach(func() { library = libraries.NewClient() book = &books.Book{ Title: "Les Miserables", Author: "Victor Hugo", } valjean = users.NewUser("Jean Valjean") }) When("the library has the book in question", func() { BeforeEach(func(ctx SpecContext) { Expect(library.Store(ctx, book)).To(Succeed()) }) Context("and the book is available", func() { It("lends it to the reader", func(ctx SpecContext) { Expect(valjean.Checkout(ctx, library, "Les Miserables")).To(Succeed()) Expect(valjean.Books()).To(ContainElement(book)) Expect(library.UserWithBook(ctx, book)).To(Equal(valjean)) }, SpecTimeout(time.Second * 5)) }) Context("but the book has already been checked out", func() { var javert *users.User BeforeEach(func(ctx SpecContext) { javert = users.NewUser("Javert") Expect(javert.Checkout(ctx, library, "Les Miserables")).To(Succeed()) }) It("tells the user", func(ctx SpecContext) { err := valjean.Checkout(ctx, library, "Les Miserables") Expect(err).To(MatchError("Les Miserables is currently checked out")) }, SpecTimeout(time.Second * 5)) It("lets the user place a hold and get notified later", func(ctx SpecContext) { Expect(valjean.Hold(ctx, library, "Les Miserables")).To(Succeed()) Expect(valjean.Holds(ctx)).To(ContainElement(book)) By("when Javert returns the book") Expect(javert.Return(ctx, library, book)).To(Succeed()) By("it eventually informs Valjean") notification := "Les Miserables is ready for pick up" Eventually(ctx, valjean.Notifications).Should(ContainElement(notification)) Expect(valjean.Checkout(ctx, library, "Les Miserables")).To(Succeed()) Expect(valjean.Books(ctx)).To(ContainElement(book)) Expect(valjean.Holds(ctx)).To(BeEmpty()) }, SpecTimeout(time.Second * 10)) }) }) When("the library does not have the book in question", func() { It("tells the reader the book is unavailable", func(ctx SpecContext) { err := valjean.Checkout(ctx, library, "Les Miserables") Expect(err).To(MatchError("Les Miserables is not in the library catalog")) }, SpecTimeout(time.Second * 5)) }) }) ``` -------------------------------- ### Commit and Publish Release Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/onsi/ginkgo/v2/RELEASING.md Commands to commit the version change, push to the repository, and create a GitHub release. ```bash git commit -m "vM.m.p" git push gh release create "vM.m.p" git fetch --tags origin master ``` -------------------------------- ### Use fmt.Sprintf for Specific Values in Structured Logs Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/go-logr/logr/README.md Demonstrates how to use fmt.Sprintf within a key's value when absolutely necessary in structured logging. This approach should be used sparingly. ```go logger.Info("unable to reflect over type", "type", fmt.Sprintf("%T")) ``` -------------------------------- ### System Call Entry Points Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/golang.org/x/sys/unix/README.md Defines the entry points for system call dispatch in hand-written assembly files. These functions handle standard and low-level system calls. ```go func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) ``` -------------------------------- ### Create and Run a File Tailer Source: https://context7.com/cloudfoundry/blackbox/llms.txt The `Tailer` struct monitors a specified log file for new lines and sends them to a configured syslog drainer. It implements the `ifrit.Runner` interface for process management. ```go package main import ( "log" "os" "code.cloudfoundry.org/go-loggregator/v10/rfc5424" "code.cloudfoundry.org/blackbox" "code.cloudfoundry.org/blackbox/syslog" ) func main() { logger := log.New(os.Stderr, "", log.LstdFlags) // Create syslog drainer drain := syslog.Drain{ Transport: "tcp", Address: "syslog.example.com:514", } drainer, err := syslog.NewDrainer( logger, drain, "my-hostname", rfc5424.StructuredData{}, 99990, ) if err != nil { log.Fatalf("could not create drainer: %s", err) } // Create tailer for a specific log file tailer := &blackbox.Tailer{ Path: "/var/log/apps/my-app/application.log", Tag: "my-app", // Used as APP-NAME in syslog messages Drainer: drainer, Logger: logger, } // Run tailer (blocks until signal received) signals := make(chan os.Signal, 1) ready := make(chan struct{}) go func() { err := tailer.Run(signals, ready) if err != nil { log.Printf("Tailer error: %s", err) } }() <-ready // Wait for tailer to be ready log.Println("Tailer is now monitoring the file") } ``` -------------------------------- ### Linux File Removal Event Behavior Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/fsnotify/fsnotify/README.md Demonstrates how file removal events are delayed until file descriptors are closed on Linux. ```go fp := os.Open("file") os.Remove("file") // CHMOD fp.Close() // REMOVE ``` -------------------------------- ### Define Blackbox YAML Configuration Source: https://context7.com/cloudfoundry/blackbox/llms.txt Configuration files define the syslog destination, source directories, and optional features like structured data or file exclusion patterns. ```yaml # Basic configuration - UDP transport hostname: my-server syslog: destination: transport: udp address: logs.example.com:514 source_dir: /var/log/apps log_filename: false --- # Advanced configuration - TLS transport with structured data hostname: production-server use_rfc3339: true max_message_size: 99990 structured_data_id: myApp@12345 structured_data_map: environment: production region: us-west-2 syslog: destination: transport: tls address: secure-logs.example.com:6514 ca: /etc/ssl/certs/syslog-ca.crt max_retries: 5 source_dir: /var/log/applications log_filename: true exclude_file_pattern: "*.debug.log" ``` -------------------------------- ### Initialize File Watcher in Go Source: https://context7.com/cloudfoundry/blackbox/llms.txt The NewFileWatcher function initializes a watcher that monitors directories and manages log tailing processes within an ifrit process group. ```go package main import ( "log" "os" "code.cloudfoundry.org/go-loggregator/v10/rfc5424" "github.com/tedsuo/ifrit" "github.com/tedsuo/ifrit/grouper" "github.com/tedsuo/ifrit/sigmon" "code.cloudfoundry.org/blackbox" "code.cloudfoundry.org/blackbox/syslog" ) func main() { logger := log.New(os.Stderr, "", log.LstdFlags) // Configure syslog drain drain := syslog.Drain{ Transport: "tcp", Address: "syslog.example.com:514", } // Optional structured data structuredData := rfc5424.StructuredData{ ID: "myApp@12345", Parameters: []rfc5424.SDParam{ {Name: "env", Value: "production"}, }, } // Create process group for managing tailers group := grouper.NewDynamic(nil, 0, 0) running := ifrit.Invoke(sigmon.New(group)) // Create and start file watcher fileWatcher := blackbox.NewFileWatcher( logger, // Logger for output "/var/log/apps", // Source directory to monitor true, // Include filename in tag group.Client(), // Dynamic group client drain, // Syslog destination "my-hostname", // Hostname for syslog messages 99990, // Max message size structuredData, // Structured data (RFC 5424) "*.old.log", // Exclude file pattern ) go fileWatcher.Watch() // Wait for shutdown signal err := <-running.Wait() if err != nil { logger.Fatalf("failed: %s", err) } } ``` -------------------------------- ### Load Configuration in Go Source: https://context7.com/cloudfoundry/blackbox/llms.txt Use LoadConfig to parse a YAML file into a Config struct. It automatically applies default values for hostname and message size. ```go package main import ( "log" "code.cloudfoundry.org/blackbox" ) func main() { // Load configuration from YAML file config, err := blackbox.LoadConfig("/etc/blackbox/config.yml") if err != nil { log.Fatalf("could not load config file: %s\n", err) } // Access configuration values log.Printf("Hostname: %s", config.Hostname) log.Printf("Source directory: %s", config.Syslog.SourceDir) log.Printf("Destination: %s://%s", config.Syslog.Destination.Transport, config.Syslog.Destination.Address) log.Printf("Max message size: %d", config.MaxMessageSize) } ``` -------------------------------- ### Run Ginkgo Specs in Parallel Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/onsi/ginkgo/v2/README.md Use the -p flag to enable parallel execution of Ginkgo specs. This is useful for speeding up test suites. ```bash ginkgo -p ``` -------------------------------- ### Persist Linux inotify Limits Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/fsnotify/fsnotify/README.md Configuration settings for /etc/sysctl.conf to persist inotify limits across reboots. ```text fs.inotify.max_user_watches=124983 fs.inotify.max_user_instances=128 ``` -------------------------------- ### Unmarshal and Marshal YAML Data in Go Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/gopkg.in/yaml.v3/README.md Demonstrates how to unmarshal YAML data into a Go struct and a map, and then marshal them back into YAML format. Ensure struct fields are public for correct unmarshalling. The `yaml:"c"` tag renames fields during marshalling/unmarshalling, and `yaml:",flow"` formats slices in flow style. ```Go package main import ( "fmt" "log" "gopkg.in/yaml.v3" ) var data = ` a: Easy! b: c: 2 d: [3, 4] ` // Note: struct fields must be public in order for unmarshal to // correctly populate the data. type T struct { A string B struct { RenamedC int `yaml:"c"` D []int `yaml:",flow"` } } func main() { t := T{} err := yaml.Unmarshal([]byte(data), &t) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- t:\n%v\n\n", t) d, err := yaml.Marshal(&t) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- t dump:\n%s\n\n", string(d)) m := make(map[interface{}]interface{}) err = yaml.Unmarshal([]byte(data), &m) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- m:\n%v\n\n", m) d, err = yaml.Marshal(&m) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- m dump:\n%s\n\n", string(d)) } ``` -------------------------------- ### Pass and use the logger Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/go-logr/logr/README.md Inject the logger into application objects to maintain decoupling from the underlying logging implementation. ```go app := createTheAppObject(logger) app.Run() ``` -------------------------------- ### Configure Linux inotify Limits Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/fsnotify/fsnotify/README.md Commands to increase the maximum number of inotify watches and instances. ```bash # The default values on Linux 5.18 sysctl fs.inotify.max_user_watches=124983 sysctl fs.inotify.max_user_instances=128 ``` -------------------------------- ### Validate a version against a constraint in Go Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/Masterminds/semver/v3/README.md Use NewConstraint and NewVersion to define and parse inputs, then call Validate to check if a version satisfies the constraint. The method returns a boolean and a slice of error messages if validation fails. ```go c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") if err != nil { // Handle constraint not being parseable. } v, err := semver.NewVersion("1.3") if err != nil { // Handle version not being parseable. } // Validate a version against a constraint. a, msgs := c.Validate(v) // a is false for _, m := range msgs { fmt.Println(m) // Loops over the errors which would read // "1.3 is greater than 1.2.3" // "1.3 is less than 1.4" } ``` -------------------------------- ### Update CHANGELOG.md Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/onsi/ginkgo/v2/RELEASING.md Generates a list of changes since the last tag and prepends them to the CHANGELOG.md file. ```bash LAST_VERSION=$(git tag --sort=version:refname | tail -n1) CHANGES=$(git log --pretty=format:'- %s [%h]' HEAD...$LAST_VERSION) echo -e "## NEXT\n\n$CHANGES\n\n### Features\n\n### Fixes\n\n### Maintenance\n\n$(cat CHANGELOG.md)" > CHANGELOG.md ``` -------------------------------- ### Minimal UDP Syslog Configuration Source: https://context7.com/cloudfoundry/blackbox/llms.txt Configure Blackbox to send logs via UDP with a maximum message size of 1024 bytes. Ensure the destination address and port are correctly specified. ```yaml hostname: server-01 syslog: destination: transport: udp address: 10.0.0.5:514 source_dir: /var/log/apps ``` -------------------------------- ### Parse Semantic Version Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/Masterminds/semver/v3/README.md Use `NewVersion` to parse a semantic version string. It attempts to coerce non-compliant versions into a valid SemVer format. An error is returned if parsing fails. ```go v, err := semver.NewVersion("1.2.3-beta.1+build345") ``` -------------------------------- ### Write RFC 5424 Syslog Message in Go Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/code.cloudfoundry.org/go-loggregator/v10/rfc5424/README.md Use this snippet to construct and write an RFC 5424 syslog message. Ensure the `time` and `os` packages are imported. The message can include structured data using `AddDatum`. ```go import ( "os" "time" "github.com/crewjam/rfc5424" ) m := rfc5424.Message{ Priority: rfc5424.Daemon | rfc5424.Info, Timestamp: time.Now(), Hostname: "myhostname", AppName: "someapp", Message: []byte("Hello, World!"), } m.AddDatum("foo@1234", "Revision", "1.2.3.4") m.WriteTo(os.Stdout) ``` -------------------------------- ### Sort Semantic Versions Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/Masterminds/semver/v3/README.md Sort a slice of semantic versions using the standard library's `sort` package. Ensure versions are parsed into `*semver.Version` objects before sorting. ```go raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} vs := make([]*semver.Version, len(raw)) for i, r := range raw { v, err := semver.NewVersion(r) if err != nil { t.Errorf("Error parsing version: %s", err) } vs[i] = v } sort.Sort(semver.Collection(vs)) ``` -------------------------------- ### Unmarshal and Marshal YAML Data in Go Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/go.yaml.in/yaml/v3/README.md Demonstrates unmarshalling YAML data into a Go struct and a map, and then marshalling them back to YAML. Ensure struct fields are public for correct unmarshalling. The 'yaml:"c"' tag renames a field during marshalling/unmarshalling, and 'yaml:",flow"' formats a slice in flow style. ```go package main import ( "fmt" "log" "go.yaml.in/yaml/v3" ) var data = ` a: Easy! b: c: 2 d: [3, 4] ` // Note: struct fields must be public in order for unmarshal to // correctly populate the data. type T struct { A string B struct { RenamedC int `yaml:"c"` D []int `yaml:",flow"` } } func main() { t := T{} err := yaml.Unmarshal([]byte(data), &t) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- t:\n%v\n\n", t) d, err := yaml.Marshal(&t) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- t dump:\n%s\n\n", string(d)) m := make(map[interface{}]interface{}) err = yaml.Unmarshal([]byte(data), &m) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- m:\n%v\n\n", m) d, err = yaml.Marshal(&m) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- m dump:\n%s\n\n", string(d)) } ``` -------------------------------- ### Create Syslog Drainer with RFC 5424 Formatting Source: https://context7.com/cloudfoundry/blackbox/llms.txt Use `NewDrainer` to create a syslog drainer that formats logs as RFC 5424 messages. It handles connection management and retries. Configure transport, address, CA certificate for TLS, and max retries. ```go package main import ( "log" "os" "code.cloudfoundry.org/go-loggregator/v10/rfc5424" "code.cloudfoundry.org/blackbox/syslog" ) func main() { logger := log.New(os.Stderr, "", log.LstdFlags) // Configure drain for TCP transport drain := syslog.Drain{ Transport: "tcp", Address: "syslog.example.com:514", MaxRetries: 5, // Exit after 5 failed connection attempts } // Configure drain for TLS transport with CA certificate tlsDrain := syslog.Drain{ Transport: "tls", Address: "secure-syslog.example.com:6514", CA: "/etc/ssl/certs/syslog-ca.crt", MaxRetries: 10, } // Structured data for RFC 5424 messages structuredData := rfc5424.StructuredData{ ID: "appMetadata@12345", Parameters: []rfc5424.SDParam{ {Name: "version", Value: "1.0.0"}, {Name: "instance", Value: "web-01"}, }, } // Create drainer drainer, err := syslog.NewDrainer( logger, drain, "my-hostname", structuredData, 99990, // Max message size in bytes ) if err != nil { log.Fatalf("could not create drainer: %s", err) } // Send log lines to syslog (tag becomes APP-NAME in RFC 5424) err = drainer.Drain("Application started successfully", "my-app") if err != nil { log.Printf("Error draining log: %s", err) } err = drainer.Drain("Processing request from user 12345", "my-app/worker") if err != nil { log.Printf("Error draining log: %s", err) } } ``` -------------------------------- ### Emit logs within application code Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/go-logr/logr/README.md Use the injected logger to emit structured logs within application methods. ```go type appObject struct { // ... other fields ... logger logr.Logger // ... other fields ... } func (app *appObject) Run() { app.logger.Info("starting up", "timestamp", time.Now()) // ... app code ... ``` -------------------------------- ### Blackbox Configuration Schema Source: https://github.com/cloudfoundry/blackbox/blob/main/README.md YAML configuration for Blackbox. Specifies hostname, syslog destination (transport, address), source directory for logs, and whether to include log filenames in tags. ```yaml hostname: this-host syslog: destination: transport: udp address: logs.example.com:1234 source_dir: /path/to/log-dir log_filename: false ``` -------------------------------- ### TCP Syslog Configuration with Retries Source: https://context7.com/cloudfoundry/blackbox/llms.txt Configure Blackbox to send logs via TCP with a specified number of retries. This configuration also includes an option to use the log filename and an exclude pattern for log files. ```yaml hostname: server-02 syslog: destination: transport: tcp address: syslog.internal:514 max_retries: 10 source_dir: /var/log/apps log_filename: true exclude_file_pattern: "*.gz" ``` -------------------------------- ### Parse RFC 5424 Syslog Message in Go Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/code.cloudfoundry.org/go-loggregator/v10/rfc5424/README.md Use this snippet to parse an incoming RFC 5424 syslog message from a reader, such as `os.Stdin`. The parsed message content will be available in `m.Message`. ```go import ( "fmt" "os" "github.com/crewjam/rfc5424" ) m := rfc5424.Message{} _, err := m.ReadFrom(os.Stdin) fmt.Printf("%s\n", m.Message) ``` -------------------------------- ### Call functions inside templates Source: https://github.com/cloudfoundry/blackbox/blob/main/vendor/github.com/go-task/slim-sprig/v3/README.md Template functions are invoked using the pipe operator, following standard Go template syntax. ```text {{ "hello!" | upper | repeat 5 }} ``` ```text HELLO!HELLO!HELLO!HELLO!HELLO! ``` -------------------------------- ### Syslog Drain Configuration Struct Source: https://context7.com/cloudfoundry/blackbox/llms.txt The `Drain` struct defines the configuration for a syslog destination, including the transport protocol, address, and TLS certificate authority. ```go package syslog // Drain configuration for syslog destination type Drain struct { // Transport protocol: "udp", "tcp", or "tls" Transport string `yaml:"transport"` // Address in host:port format Address string `yaml:"address"` // Path to CA certificate file (required for TLS transport) CA string `yaml:"ca"` // Maximum connection retry attempts (0 = unlimited) MaxRetries int `yaml:"max_retries"` } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.