Conventions

Naming

The Jaeger library follows standard Go naming conventions, using https://golang.org/doc/effective_go.html#names as the source for best practices.

  • Packages: Packages should be named in lowercase, using a hyphen to separate words.
  • Types: Types should be named in CamelCase, using the first letter of each word capitalized.
  • Variables: Variables should be named in lowercase, using an underscore to separate words.
  • Functions: Functions should be named in CamelCase, using the first letter of each word capitalized.
  • Constants: Constants should be named in uppercase, using an underscore to separate words.
  • Interfaces: Interfaces should be named in CamelCase, using the first letter of each word capitalized.

Example

// metrics/go-kit/influx/factory.go
          type factory struct {
              client *influx.Influx
          }
          
          // metrics/factory.go
          // NSOptions defines the name and tags map associated with a factory namespace
          type NSOptions struct {
              Name string
              Tags map[string]string
          }
          
          // Options defines the information associated with a metric
          type Options struct {
              Name string
              Tags map[string]string
              Help string
          }
          
          // sample/sample.go
          // SayHello is a sample function
          func SayHello() {
              fmt.Println("Hello, playground")
          }
          
          // metrics/adapters/tagless.go
          // TaglessOptions defines the information associated with a metric
          type TaglessOptions struct {
              Name string
              Help string
          }
          
          // metrics/expvar/factory.go
          type factory struct {
              factory xkit.Factory
          }
          
          // metrics/prometheus/factory.go
          // WithRegisterer returns an option that sets the registerer.
          // If not used we fallback to prometheus.DefaultRegisterer.
          func WithRegisterer(registerer prometheus.Registerer) Option {
              return func(opts *options) {
                  opts.registerer = registerer
              }
          }
          
          type options struct {
              registerer prometheus.Registerer
              buckets    []float64
              separator  Separator
          }
          
          type gauge struct {
              gauge prometheus.Gauge
          }
          
          type counter struct {
              counter prometheus.Counter
          }
          
          // metrics/go-kit/factory.go
          type factory struct {
              scope    string
              tags     map[string]string
              factory  Factory
              scopeSep string
              tagsSep  string
              tagKVSep string
          }
          
          // metrics/tally/metrics.go
          // Gauge is an adapter from go-tally Gauge to jaeger-lib Gauge
          type Gauge struct {
              gauge tally.Gauge
          }
          
          // metrics/multi/multi.go
          type timer struct {
              timers []metrics.Timer
          }
          
          type gauge struct {
              gauges []metrics.Gauge
          }
          

Error Handling

The Jaeger library uses the https://github.com/pkg/errors package to handle errors.

  • Error wrapping: Errors should be wrapped using the Wrap function from the errors package.
  • Error formatting: Error messages should be clear and concise.
  • Error handling: Errors should be handled appropriately, either by logging or returning them to the caller.

Example

// Example error handling with wrapping
          // ...
          err := someFunction()
          if err != nil {
              return errors.Wrap(err, "failed to perform some action")
          }
          // ...
          

Documentation

The Jaeger library uses https://godoc.org/ to generate documentation.

  • Comments: Comments should be used to document code.
  • Godoc: Godoc tags should be used to generate documentation for public API.

Example

// metrics/go-kit/influx/factory.go
          // factory is an influxdb metrics factory implementation for go-kit
          type factory struct {
              client *influx.Influx
          }
          
          // metrics/factory.go
          // NSOptions defines the name and tags map associated with a factory namespace
          type NSOptions struct {
              Name string
              Tags map[string]string
          }
          
          // Options defines the information associated with a metric
          type Options struct {
              Name string
              Tags map[string]string
              Help string
          }
          
          // sample/sample.go
          // SayHello is a sample function
          func SayHello() {
              fmt.Println("Hello, playground")
          }
          
          // metrics/adapters/tagless.go
          // TaglessOptions defines the information associated with a metric
          type TaglessOptions struct {
              Name string
              Help string
          }
          
          // metrics/expvar/factory.go
          // factory is an expvar metrics factory implementation for go-kit
          type factory struct {
              factory xkit.Factory
          }
          
          // metrics/prometheus/factory.go
          // WithRegisterer returns an option that sets the registerer.
          // If not used we fallback to prometheus.DefaultRegisterer.
          func WithRegisterer(registerer prometheus.Registerer) Option {
              return func(opts *options) {
                  opts.registerer = registerer
              }
          }
          
          type options struct {
              registerer prometheus.Registerer
              buckets    []float64
              separator  Separator
          }
          
          type gauge struct {
              gauge prometheus.Gauge
          }
          
          type counter struct {
              counter prometheus.Counter
          }
          
          // metrics/go-kit/factory.go
          // factory is a go-kit metrics factory implementation for go-kit
          type factory struct {
              scope    string
              tags     map[string]string
              factory  Factory
              scopeSep string
              tagsSep  string
              tagKVSep string
          }
          
          // metrics/tally/metrics.go
          // Gauge is an adapter from go-tally Gauge to jaeger-lib Gauge
          type Gauge struct {
              gauge tally.Gauge
          }
          
          // metrics/multi/multi.go
          // timer is an adapter from jaeger-lib Timer to multiple metric implementations
          type timer struct {
              timers []metrics.Timer
          }
          
          // gauge is an adapter from jaeger-lib Gauge to multiple metric implementations
          type gauge struct {
              gauges []metrics.Gauge
          }
          

Testing

The Jaeger library uses https://pkg.go.dev/testing to write tests.

  • Unit tests: Unit tests should be used to test individual functions and methods.
  • Integration tests: Integration tests should be used to test the interaction between different components.
  • Test coverage: Test coverage should be high.

Example

// metrics/go-kit/influx/factory_test.go
          func TestFactory_NewNS(t *testing.T) {
              // ...
          }
          

Contribution

The Jaeger library welcomes contributions from the community.

  • Pull requests: Contributions should be made via pull requests.
  • DCO: All contributions must be signed off using the Developer Certificate of Origin (DCO).
  • Code style: All code should conform to the Go style guide.
  • Testing: All new code should be tested.

Example

// Example contribution with DCO
          // ...
          Signed-off-by: John Doe <[email protected]>
          // ...
          

Top-Level Directory Explanations

metrics/ - This directory contains the metrics implementation for the Jaeger Tracing library.

metrics/adapters/ - This subdirectory contains the various metric adapters for different backends.

metrics/expvar/ - This subdirectory contains the implementation for exposing metrics as HTTP endpoints using the expvar package.

metrics/fork/ - This subdirectory contains the implementation for forking metrics between processes.

metrics/go-kit/ - This subdirectory contains the Go-Kit integration for the Jaeger Tracing library.

metrics/go-kit/expvar/ - This subdirectory contains the expvar implementation for the Go-Kit integration.

metrics/go-kit/influx/ - This subdirectory contains the InfluxDB implementation for the Go-Kit integration.

metrics/metricstest/ - This subdirectory contains the testing implementation for the metrics.

metrics/multi/ - This subdirectory contains the implementation for collecting metrics from multiple sources.

metrics/prometheus/ - This subdirectory contains the Prometheus implementation for the Jaeger Tracing library.

metrics/tally/ - This subdirectory contains the implementation for counting metrics using the tally package.

sample/ - This directory contains a sample implementation for the Jaeger Tracing library.

scripts/ - This directory contains various scripts for the project.