build(deps): bump github.com/riandyrn/otelchi from 0.5.1 to 0.7.0

Bumps [github.com/riandyrn/otelchi](https://github.com/riandyrn/otelchi) from 0.5.1 to 0.7.0.
- [Release notes](https://github.com/riandyrn/otelchi/releases)
- [Changelog](https://github.com/riandyrn/otelchi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/riandyrn/otelchi/compare/v0.5.1...v0.7.0)

---
updated-dependencies:
- dependency-name: github.com/riandyrn/otelchi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2024-04-24 09:21:50 +02:00
committed by Ralf Haferkamp
parent e081e9e0a5
commit 50ad489d30
29 changed files with 1139 additions and 1678 deletions
+149
View File
@@ -0,0 +1,149 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [0.7.0] - 2024-04-22
### ⚠️ Notice ⚠️
This release is the last to support Go `1.18`. The next release will require at least Go `1.19`.
### Changed
- Upgrade to `v1.14.0` of `go.opentelemetry.io/otel`. (#38)
- Upgrade to `v1.17.0` of `go.opentelemetry.io/otel/semconv`. (#38)
- Adjust Go version for both `examples/basic` & `examples/multi-services` to `1.18` & `go.opentelemetry.io/otel` to `v1.14.0`. (#38)
- Change `http.server_name` attributes to `net.host.name`, this is because semconv is removing this attribute for http. (#38)
### Removed
- Remove `http.target` attribute on implementation & tests based on [this comment](https://github.com/open-telemetry/opentelemetry-go/blob/v1.17.0/semconv/internal/v2/http.go#L160-L165). (#39)
- Drop support for Go `<1.18`. (#38)
## [0.6.0] - 2024-04-02
### ⚠️ Notice ⚠️
This release is the last to support Go `1.15`. The next release will require at least Go `1.18`.
### Added
- Add `WithTraceIDResponseHeader` option to enable adding trace id into response header. (#36)
- Add multiple go versions test scripts for local and CI pipeline. (#29)
- Add compatibility testing for `ubuntu`, `macos` and `windows`. (#32)
- Add repo essentials docs. (#33)
### Changed
- Upgrade to `v5.0.12` of `go-chi/chi`. (#29)
- Upgrade to `v1.10.0` of `go.opentelemetry.io/otel`. (#29)
- Upgrade to `v1.12.0` of `go.opentelemetry.io/otel/semconv`. (#29)
- Set the required go version for both `examples/basic` & `examples/multi-services` to `1.15`, `go-chi/chi` to `v5.0.12`, & `go.opentelemetry.io/otel` to `v1.10.0` (#35)
## [0.5.2] - 2024-03-25
### Fixed
- Fix empty status code. (#30)
### Changed
- Return `http.StatusOK` (200) as a default `http.status_code` span attribute. (#30)
## [0.5.1] - 2023-02-18
### Fixed
- Fix broken empty routes. (#18)
### Changed
- Upgrade to `v5.0.8` of `go-chi/chi`.
## [0.5.0] - 2022-10-02
### Added
- Add multi services example. (#9)
- Add `WithFilter()` option to ignore tracing in certain endpoints. (#11)
## [0.4.0] - 2022-02-22
### Added
- Add Option `WithRequestMethodInSpanName()` to handle vendor that do not include HTTP request method as mentioned in #6. (#7)
- Refine description for `WithChiRoutes()` option to announce it is possible to override the span name in underlying handler with this option.
### Changed
## [0.3.0] - 2022-01-18
### Fixed
- Fix both `docker-compose.yml` & `Dockerfile` in the example. (#5)
### Added
- Add `WithChiRoutes()` option to make the middleware able to determine full route pattern on span creation. (#5)
- Set all known span attributes on span creation rather than set them after request is being executed. (#5)
## [0.2.1] - 2022-01-08
### Added
- Add build example to CI pipeline. (#2)
### Changed
- Use `ctx.RoutePattern()` to get span name, this is to strip out noisy wildcard pattern. (#1)
## [0.2.0] - 2021-10-18
### Added
- Set service name on tracer provider from code example.
### Changed
- Update dependencies in go.mod
- Upgrade to `v1.0.1` of `go.opentelemetry.io/otel`.
- Upgrade to `v5.0.4` of `go-chi/chi`.
- Update latest test to use `otelmux` format.
### Removed
- Remove `HTTPResponseContentLengthKey`
- Remove `HTTPTargetKey`, since automatically set in `HTTPServerAttributesFromHTTPRequest`
## [0.1.0] - 2021-08-11
This is the first release of otelchi.
It contains instrumentation for trace and depends on:
- otel => `v1.0.0-RC2`
- go-chi/chi => `v5.0.3`
### Added
- Instrumentation for trace.
- CI files.
- Example code for a basic usage.
- Apache-2.0 license.
[Unreleased]: https://github.com/riandyrn/otelchi/compare/v0.7.0...HEAD
[0.7.0]: https://github.com/riandyrn/otelchi/releases/tag/v0.7.0
[0.6.0]: https://github.com/riandyrn/otelchi/releases/tag/v0.6.0
[0.5.2]: https://github.com/riandyrn/otelchi/releases/tag/v0.5.2
[0.5.1]: https://github.com/riandyrn/otelchi/releases/tag/v0.5.1
[0.5.0]: https://github.com/riandyrn/otelchi/releases/tag/v0.5.0
[0.4.0]: https://github.com/riandyrn/otelchi/releases/tag/v0.4.0
[0.3.0]: https://github.com/riandyrn/otelchi/releases/tag/v0.3.0
[0.2.1]: https://github.com/riandyrn/otelchi/releases/tag/v0.2.1
[0.2.0]: https://github.com/riandyrn/otelchi/releases/tag/v0.2.0
[0.1.0]: https://github.com/riandyrn/otelchi/releases/tag/v0.1.0
+1
View File
@@ -0,0 +1 @@
* @riandyrn @ilhamsyahids @mustafasegf @ProtozoaJr
+26 -1
View File
@@ -1,4 +1,29 @@
.PHONY: *
GO_VERSIONS="1.18 1.19 1.20"
# This is the command that will be used to run the tests
go-test:
go build .
go test ./...
# This is the command that will be used to run the tests in a Docker container, useful when executing the test locally
test:
go test -v ./...
docker build \
-t go-test \
--build-arg GO_VERSIONS=${GO_VERSIONS} \
-f ./test/infras/Dockerfile . && \
docker run --rm go-test
make test-build-examples
test-build-examples:
make test-build-basic-example
make test-build-multi-services-example
test-build-basic-example:
docker build -f ./examples/basic/Dockerfile .
test-build-multi-services-example:
docker build -f ./examples/multi-services/back-svc/Dockerfile .
docker build -f ./examples/multi-services/front-svc/Dockerfile .
+48
View File
@@ -0,0 +1,48 @@
# Release Process
This document explains how to create releases in this project in each release scenario.
Currently there are 2 release procedures for this project:
- [Latest Release](#latest-release)
- [Non-Latest Release](#non-latest-release)
## Latest Release
This procedure is used when we want to create new release from the latest development edge (latest commit in the `master` branch).
The steps for this procedure are the following:
1. Create a new branch from the `master` branch with the following name format: `pre_release/v{MAJOR}.{MINOR}.{BUILD}`. For example, if we want to release for version `0.6.0`, we will first create a new branch from the `master` called `pre_release/v0.6.0`.
2. Update method `Version()` in `version.go` to return the target version.
3. Update the `CHANGELOG.md` to include all the notable changes.
4. Create a new PR from this branch to `master` with the title: `Release v{MAJOR}.{MINOR}.{BUILD}` (e.g `Release v0.6.0`).
5. At least one maintainer should approve the PR. However if the PR is created by the repo owner, it doesn't need to get approval from other maintainers.
6. Upon approval, the PR will be merged to `master` and the branch will be deleted.
7. Create new release from the `master` branch.
8. Set the title to `Release v{MAJOR}.{MINOR}.{BUILD}` (e.g `Release v0.6.0`).
9. Set the newly release tag using this format: `v{MAJOR}.{MINOR}.{BUILD}` (e.g `v0.6.0`).
10. Set the description of the release to match with the content inside `CHANGELOG.md`.
11. Set the release as the latest release.
12. Publish the release.
13. Done.
## Non-Latest Release
This procedure is used when we need to create fix or patch for the older releases. Consider the following scenario:
1. For example our latest release is version `0.7.1` which has the minimum go version `1.18`.
2. Let say our user got a critical bug in version `0.6.0` which has the minimum go version `1.15`.
3. Due to some constraints, this user cannot upgrade his/her minimum go version.
4. We decided to create fix for this version by releasing `0.6.1`.
In this scenario, the procedure is the following:
1. Create a new branch from the version that we want to patch.
2. We name the new branch with the increment in the build value. So for example if we want to create patch for `0.6.0`, then we should create new branch with name: `patch_release/v0.6.1`.
3. We create again new branch that will use `patch_release/v0.6.1` as base. Let say `fix/handle-cve-233`.
4. We will push any necessary changes to `fix/handle-cve-233`.
5. Create a new PR that target `patch_release/v0.6.1`.
6. Follow step `2-10` as described in the [Latest Release](#latest-release).
7. Publish the release without setting the release as the latest release.
8. Done.
+16
View File
@@ -8,6 +8,8 @@ import (
oteltrace "go.opentelemetry.io/otel/trace"
)
const defaultTraceResponseHeaderKey = "X-Trace-Id"
// config is used to configure the mux middleware.
type config struct {
TracerProvider oteltrace.TracerProvider
@@ -15,6 +17,7 @@ type config struct {
ChiRoutes chi.Routes
RequestMethodInSpanName bool
Filter func(r *http.Request) bool
TraceResponseHeaderKey string
}
// Option specifies instrumentation configuration options.
@@ -80,3 +83,16 @@ func WithFilter(filter func(r *http.Request) bool) Option {
cfg.Filter = filter
})
}
// WithTraceIDResponseHeader enables adding trace id into response header.
// It accepts a function that generates the header key name. If this parameter
// function set to `nil` the default header key which is `X-Trace-Id` will be used.
func WithTraceIDResponseHeader(headerKeyFunc func() string) Option {
return optionFunc(func(cfg *config) {
if headerKeyFunc == nil {
cfg.TraceResponseHeaderKey = defaultTraceResponseHeaderKey // use default trace header
} else {
cfg.TraceResponseHeaderKey = headerKeyFunc()
}
})
}
+36 -28
View File
@@ -10,8 +10,8 @@ import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/propagation"
otelcontrib "go.opentelemetry.io/contrib"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
"go.opentelemetry.io/otel/semconv/v1.17.0/httpconv"
oteltrace "go.opentelemetry.io/otel/trace"
)
@@ -32,32 +32,35 @@ func Middleware(serverName string, opts ...Option) func(next http.Handler) http.
}
tracer := cfg.TracerProvider.Tracer(
tracerName,
oteltrace.WithInstrumentationVersion(otelcontrib.SemVersion()),
oteltrace.WithInstrumentationVersion(Version()),
)
if cfg.Propagators == nil {
cfg.Propagators = otel.GetTextMapPropagator()
}
return func(handler http.Handler) http.Handler {
return traceware{
serverName: serverName,
tracer: tracer,
propagators: cfg.Propagators,
handler: handler,
chiRoutes: cfg.ChiRoutes,
reqMethodInSpanName: cfg.RequestMethodInSpanName,
filter: cfg.Filter,
serverName: serverName,
tracer: tracer,
propagators: cfg.Propagators,
handler: handler,
chiRoutes: cfg.ChiRoutes,
reqMethodInSpanName: cfg.RequestMethodInSpanName,
filter: cfg.Filter,
traceResponseHeaderKey: cfg.TraceResponseHeaderKey,
}
}
}
type traceware struct {
serverName string
tracer oteltrace.Tracer
propagators propagation.TextMapPropagator
handler http.Handler
chiRoutes chi.Routes
reqMethodInSpanName bool
filter func(r *http.Request) bool
serverName string
tracer oteltrace.Tracer
propagators propagation.TextMapPropagator
handler http.Handler
chiRoutes chi.Routes
reqMethodInSpanName bool
filter func(r *http.Request) bool
traceResponseHeaderKey string
}
type recordingResponseWriter struct {
@@ -75,13 +78,12 @@ var rrwPool = &sync.Pool{
func getRRW(writer http.ResponseWriter) *recordingResponseWriter {
rrw := rrwPool.Get().(*recordingResponseWriter)
rrw.written = false
rrw.status = 0
rrw.status = http.StatusOK
rrw.writer = httpsnoop.Wrap(writer, httpsnoop.Hooks{
Write: func(next httpsnoop.WriteFunc) httpsnoop.WriteFunc {
return func(b []byte) (int, error) {
if !rrw.written {
rrw.written = true
rrw.status = http.StatusOK
}
return next(b)
}
@@ -125,23 +127,29 @@ func (tw traceware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// if we have access to chi routes, we could extract the route pattern beforehand.
spanName := ""
routePattern := ""
spanAttributes := httpconv.ServerRequest(tw.serverName, r)
if tw.chiRoutes != nil {
rctx := chi.NewRouteContext()
if tw.chiRoutes.Match(rctx, r.Method, r.URL.Path) {
routePattern = rctx.RoutePattern()
spanName = addPrefixToSpanName(tw.reqMethodInSpanName, r.Method, routePattern)
spanAttributes = append(spanAttributes, semconv.HTTPRoute(routePattern))
}
}
ctx, span := tw.tracer.Start(
ctx, spanName,
oteltrace.WithAttributes(semconv.NetAttributesFromHTTPRequest("tcp", r)...),
oteltrace.WithAttributes(semconv.EndUserAttributesFromHTTPRequest(r)...),
oteltrace.WithAttributes(semconv.HTTPServerAttributesFromHTTPRequest(tw.serverName, routePattern, r)...),
oteltrace.WithAttributes(spanAttributes...),
oteltrace.WithSpanKind(oteltrace.SpanKindServer),
)
defer span.End()
// put trace_id to response header only when WithTraceResponseHeaderKey is used
if len(tw.traceResponseHeaderKey) > 0 && span.SpanContext().HasTraceID() {
w.Header().Add(tw.traceResponseHeaderKey, span.SpanContext().TraceID().String())
}
// get recording response writer
rrw := getRRW(w)
defer putRRW(rrw)
@@ -150,26 +158,26 @@ func (tw traceware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
r = r.WithContext(ctx)
tw.handler.ServeHTTP(rrw.writer, r)
// set span name & http route attribute if necessary
// set span name & http route attribute if route pattern cannot be determined
// during span creation
if len(routePattern) == 0 {
routePattern = chi.RouteContext(r.Context()).RoutePattern()
span.SetAttributes(semconv.HTTPRouteKey.String(routePattern))
span.SetAttributes(semconv.HTTPRoute(routePattern))
spanName = addPrefixToSpanName(tw.reqMethodInSpanName, r.Method, routePattern)
span.SetName(spanName)
}
// set status code attribute
span.SetAttributes(semconv.HTTPStatusCodeKey.Int(rrw.status))
span.SetAttributes(semconv.HTTPStatusCode(rrw.status))
// set span status
spanStatus, spanMessage := semconv.SpanStatusFromHTTPStatusCode(rrw.status)
span.SetStatus(spanStatus, spanMessage)
span.SetStatus(httpconv.ServerStatus(rrw.status))
}
func addPrefixToSpanName(shouldAdd bool, prefix, spanName string) string {
// in chi v5.0.8, the root route will be returned has an empty string
// (see github.com/go-chi/chi/v5@v5.0.8/context.go:126)
// (see https://github.com/go-chi/chi/blob/v5.0.8/context.go#L126)
if spanName == "" {
spanName = "/"
}
+6
View File
@@ -0,0 +1,6 @@
package otelchi
// Version is the current release version of otelchi in use.
func Version() string {
return "0.7.0"
}