Open telemetry integration (#3972)
This PR adds opentelemetry and chi wrapper to have basic instrumentation <!--start release-notes-assistant--> ## Draft release notes <!--URL:https://codeberg.org/forgejo/forgejo--> - Features - [PR](https://codeberg.org/forgejo/forgejo/pulls/3972): <!--number 3972 --><!--line 0 --><!--description YWRkIHN1cHBvcnQgZm9yIGJhc2ljIHJlcXVlc3QgdHJhY2luZyB3aXRoIG9wZW50ZWxlbWV0cnk=-->add support for basic request tracing with opentelemetry<!--description--> <!--end release-notes-assistant--> Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3972 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Co-authored-by: TheFox0x7 <thefox0x7@gmail.com> Co-committed-by: TheFox0x7 <thefox0x7@gmail.com>
This commit is contained in:
parent
7c74def6ff
commit
c738542201
19 changed files with 1281 additions and 10 deletions
|
@ -18,6 +18,7 @@ import (
|
|||
"gitea.com/go-chi/session"
|
||||
"github.com/chi-middleware/proxy"
|
||||
chi "github.com/go-chi/chi/v5"
|
||||
"github.com/riandyrn/otelchi"
|
||||
)
|
||||
|
||||
// ProtocolMiddlewares returns HTTP protocol related middlewares, and it provides a global panic recovery
|
||||
|
@ -68,6 +69,9 @@ func ProtocolMiddlewares() (handlers []any) {
|
|||
if setting.IsAccessLogEnabled() {
|
||||
handlers = append(handlers, context.AccessLogger())
|
||||
}
|
||||
if setting.IsOpenTelemetryEnabled() {
|
||||
handlers = append(handlers, otelchi.Middleware("forgejo"))
|
||||
}
|
||||
|
||||
return handlers
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/markup/external"
|
||||
"code.gitea.io/gitea/modules/opentelemetry"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/ssh"
|
||||
"code.gitea.io/gitea/modules/storage"
|
||||
|
@ -110,6 +111,7 @@ func InitWebInstallPage(ctx context.Context) {
|
|||
|
||||
// InitWebInstalled is for global installed configuration.
|
||||
func InitWebInstalled(ctx context.Context) {
|
||||
mustInitCtx(ctx, opentelemetry.Init)
|
||||
mustInitCtx(ctx, git.InitFull)
|
||||
log.Info("Git version: %s (home: %s)", git.VersionInfo(), git.HomeDir())
|
||||
|
||||
|
|
|
@ -4,12 +4,23 @@
|
|||
package install
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
"code.gitea.io/gitea/modules/opentelemetry"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestRoutes(t *testing.T) {
|
||||
|
@ -36,3 +47,43 @@ func TestRoutes(t *testing.T) {
|
|||
func TestMain(m *testing.M) {
|
||||
unittest.MainTest(m)
|
||||
}
|
||||
|
||||
func TestOtelChi(t *testing.T) {
|
||||
ServiceName := "forgejo-otelchi" + uuid.NewString()
|
||||
|
||||
otelURL, ok := os.LookupEnv("TEST_OTEL_URL")
|
||||
if !ok {
|
||||
t.Skip("TEST_OTEL_URL not set")
|
||||
}
|
||||
traceEndpoint, err := url.Parse(otelURL)
|
||||
require.NoError(t, err)
|
||||
config := &setting.OtelExporter{
|
||||
Endpoint: traceEndpoint,
|
||||
Protocol: "grpc",
|
||||
}
|
||||
|
||||
defer test.MockVariableValue(&setting.OpenTelemetry.Enabled, true)()
|
||||
defer test.MockVariableValue(&setting.OpenTelemetry.Traces, "otlp")() // Required due to lazy loading
|
||||
defer test.MockVariableValue(&setting.OpenTelemetry.ServiceName, ServiceName)()
|
||||
defer test.MockVariableValue(&setting.OpenTelemetry.OtelTraces, config)()
|
||||
|
||||
require.NoError(t, opentelemetry.Init(context.Background()))
|
||||
r := Routes()
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req := httptest.NewRequest("GET", "/e/img/gitea.svg", nil)
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
traceEndpoint.Host = traceEndpoint.Hostname() + ":16686"
|
||||
traceEndpoint.Path = "/api/services"
|
||||
|
||||
require.EventuallyWithT(t, func(collect *assert.CollectT) {
|
||||
resp, err := http.Get(traceEndpoint.String())
|
||||
require.NoError(t, err)
|
||||
|
||||
apiResponse, err := io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Contains(collect, string(apiResponse), ServiceName)
|
||||
}, 15*time.Second, 1*time.Second)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue