• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

armory / dinghy / 9704674769

27 Jun 2024 10:54PM UTC coverage: 41.534% (-13.0%) from 54.581%
9704674769

Pull #187

github

jasonmcintosh
fix: Builds to use parallel checks
Pull Request #187: chore: Upgrade to golang 1.22, sprout vs. spring, and other updates and fixes plus plank upgrade to fix deletes

8 of 22 new or added lines in 8 files covered. (36.36%)

1 existing line in 1 file now uncovered.

2252 of 5422 relevant lines covered (41.53%)

14.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

7.94
/pkg/web/middleware.go
1
/*
2
* Copyright 2019 Armory, Inc.
3

4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
7

8
*    http://www.apache.org/licenses/LICENSE-2.0
9

10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
15
 */
16

17
package web
18

19
import (
20
        "context"
21
        "errors"
22
        "net/http"
23
        "strings"
24

25
        log "github.com/sirupsen/logrus"
26
        "go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
27
        sdktrace "go.opentelemetry.io/otel/sdk/trace"
28
        "go.opentelemetry.io/otel/trace"
29
)
30

31
type statusLoggingResponseWriter struct {
32
        http.ResponseWriter
33
        status    int
34
        bodyBytes int
35
}
36

37
func (w *statusLoggingResponseWriter) WriteHeader(code int) {
×
38
        w.status = code
×
39
        w.ResponseWriter.WriteHeader(code)
×
40
}
×
41
func (w *statusLoggingResponseWriter) Write(data []byte) (int, error) {
×
42
        length, err := w.ResponseWriter.Write(data)
×
43
        w.bodyBytes += length
×
44
        return length, err
×
45
}
×
46

47
func RequestLoggingMiddleware(h http.Handler) http.Handler {
×
48
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
×
49
                requestFields := log.Fields{
×
50
                        "uri":    r.URL.RequestURI(),
×
51
                        "method": r.Method,
×
52
                }
×
53
                log.WithFields(requestFields).Info("incoming request")
×
54

×
55
                wrappedWriter := &statusLoggingResponseWriter{w, http.StatusOK, 0}
×
56
                defer func() {
×
57
                        fields := requestFields
×
58
                        fields["status"] = wrappedWriter.status
×
59
                        log.WithFields(fields).Infof("outgoing request")
×
60
                }()
×
61
                h.ServeHTTP(wrappedWriter, r)
×
62
        })
63
}
64

65
type TraceSettings interface {
66
        TraceExtract() func(handler http.Handler) http.Handler
67
}
68

69
type TraceContextKey struct{}
70

71
func extractTraceContext(ctx context.Context) (*TraceContext, error) {
20✔
72
        v, ok := ctx.Value(TraceContextKey{}).(TraceContext)
20✔
73
        if !ok {
40✔
74
                return nil, errors.New("unable to extract trace context from request")
20✔
75
        }
20✔
76
        return &v, nil
×
77
}
78

79
// TraceContext maps to the w3c traceparent header  https://w3c.github.io/trace-context/#traceparent-header
80
type TraceContext struct {
81
        Version string
82
        TraceID string
83
        // SpanID is also known as the parent id
84
        // since that is the upstream service's active span when the request was made
85
        SpanID  string
86
        Sampled string
87
}
88

89
func ExtractTraceContextHeaders(headers http.Header) TraceContext {
×
90
        var tc TraceContext
×
91
        tp := headers.Get("traceparent")
×
92
        // traceparent follows format: ${supportedVersion}-${traceID}-${spanID}-${samplingRate}
×
93
        if tp != "" {
×
94
                tpParts := strings.Split(tp, "-")
×
95
                // Only accept properly formatted header
×
96
                if len(tpParts) == 4 {
×
97
                        // We only need trace id for now since version, sampling rate, and span id aren't relevant for correlating logs to traces
×
98
                        tc.TraceID = tpParts[1]
×
99
                        tc.SpanID = tpParts[2]
×
100
                }
×
101
        } else {
×
NEW
102
                exporter, err := stdouttrace.New(stdouttrace.WithPrettyPrint())
×
103
                if err != nil {
×
104
                        log.Errorf("failed to initialize stdout export pipeline: %v", err)
×
105
                        return tc
×
106
                }
×
107
                ctx := context.Background()
×
108
                bsp := sdktrace.NewBatchSpanProcessor(exporter)
×
109
                tp := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(bsp))
×
110
                tracer := tp.Tracer("dinghyTracer")
×
111
                var parentSpan trace.Span
×
112
                ctx, parentSpan = tracer.Start(ctx, "parentSpan")
×
113
                defer parentSpan.End()
×
NEW
114
                if parentSpan.SpanContext().HasTraceID() {
×
NEW
115
                        tc.TraceID = parentSpan.SpanContext().TraceID().String()
×
NEW
116
                }
×
NEW
117
                if parentSpan.SpanContext().HasSpanID() {
×
NEW
118
                        tc.SpanID = parentSpan.SpanContext().SpanID().String()
×
NEW
119
                }
×
120

121
                // Handle this error in a sensible manner where possible
122
                defer func() { _ = tp.Shutdown(ctx) }()
×
123

124
        }
125
        return tc
×
126
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc