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

mendersoftware / mender-server / 1961830404

01 Aug 2025 06:29PM UTC coverage: 65.815% (+0.3%) from 65.555%
1961830404

Pull #849

gitlab-ci

web-flow
chore: bump the backend-docker-dependencies group across 10 directories with 2 updates

Bumps the backend-docker-dependencies group with 2 updates in the /backend/services/create-artifact-worker directory: golang and alpine.
Bumps the backend-docker-dependencies group with 1 update in the /backend/services/deployments directory: golang.
Bumps the backend-docker-dependencies group with 1 update in the /backend/services/deviceauth directory: golang.
Bumps the backend-docker-dependencies group with 1 update in the /backend/services/deviceconfig directory: golang.
Bumps the backend-docker-dependencies group with 1 update in the /backend/services/deviceconnect directory: golang.
Bumps the backend-docker-dependencies group with 1 update in the /backend/services/inventory directory: golang.
Bumps the backend-docker-dependencies group with 1 update in the /backend/services/iot-manager directory: golang.
Bumps the backend-docker-dependencies group with 1 update in the /backend/services/reporting directory: golang.
Bumps the backend-docker-dependencies group with 1 update in the /backend/services/useradm directory: golang.
Bumps the backend-docker-dependencies group with 1 update in the /backend/services/workflows directory: golang.


Updates `golang` from 1.24.4 to 1.24.5

Updates `alpine` from 3.22.0 to 3.22.1

Updates `golang` from 1.24.4 to 1.24.5

Updates `golang` from 1.24.4 to 1.24.5

Updates `golang` from 1.24.4 to 1.24.5

Updates `golang` from 1.24.4 to 1.24.5

Updates `golang` from 1.24.4 to 1.24.5

Updates `golang` from 1.24.4 to 1.24.5

Updates `golang` from 1.24.4 to 1.24.5

Updates `golang` from 1.24.4 to 1.24.5

Updates `golang` from 1.24.4 to 1.24.5

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.24.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: backend-docker-dependencies
- dependency-name: alpine
  dependency-version: 3.22.1
  dependency-type: direct:production... (continued)
Pull Request #849: chore: bump the backend-docker-dependencies group across 10 directories with 2 updates

29335 of 44572 relevant lines covered (65.81%)

1.44 hits per line

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

81.44
/backend/pkg/accesslog/middleware_gin.go
1
// Copyright 2024 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14

15
package accesslog
16

17
import (
18
        "context"
19
        "fmt"
20
        "net"
21
        "net/http"
22
        "strings"
23
        "time"
24

25
        "github.com/gin-gonic/gin"
26
        "github.com/pkg/errors"
27
        "github.com/sirupsen/logrus"
28

29
        "github.com/mendersoftware/mender-server/pkg/log"
30
        "github.com/mendersoftware/mender-server/pkg/rest.utils"
31
)
32

33
type AccessLogger struct {
34
        DisableLog   func(c *gin.Context) bool
35
        ClientIPHook func(r *http.Request) net.IP
36
}
37

38
func formatPathParams(params gin.Params) string {
9✔
39
        var b strings.Builder
9✔
40
        lastIdx := len(params) - 1
9✔
41
        delimiter := " "
9✔
42
        for i, p := range params {
18✔
43
                if i == lastIdx {
18✔
44
                        delimiter = ""
9✔
45
                }
9✔
46
                key := strings.TrimPrefix(p.Key, ":")
9✔
47
                fmt.Fprintf(&b, "%s=%s%s", key, p.Value, delimiter)
9✔
48
        }
49
        return b.String()
9✔
50
}
51

52
func (a AccessLogger) LogFunc(
53
        ctx context.Context,
54
        c *gin.Context,
55
        startTime time.Time,
56
) {
9✔
57
        logCtx := logrus.Fields{
9✔
58
                "method":      c.Request.Method,
9✔
59
                "path":        c.FullPath(),
9✔
60
                "path_params": formatPathParams(c.Params),
9✔
61
                "qs":          c.Request.URL.RawQuery,
9✔
62
                "ts": startTime.
9✔
63
                        Truncate(time.Millisecond).
9✔
64
                        Format(time.RFC3339Nano),
9✔
65
                "type":      c.Request.Proto,
9✔
66
                "useragent": c.Request.UserAgent(),
9✔
67
        }
9✔
68
        if a.ClientIPHook != nil {
9✔
69
                logCtx["clientip"] = a.ClientIPHook(c.Request)
×
70
        }
×
71
        lc := fromContext(ctx)
9✔
72
        if lc != nil {
18✔
73
                lc.addFields(logCtx)
9✔
74
        }
9✔
75
        if r := recover(); r != nil {
9✔
76
                trace := collectTrace()
×
77
                logCtx["trace"] = trace
×
78
                logCtx["panic"] = r
×
79

×
80
                func() {
×
81
                        // Try to respond with an internal server error.
×
82
                        // If the connection is broken it might panic again.
×
83
                        defer func() { recover() }() // nolint:errcheck
×
84
                        rest.RenderError(c,
×
85
                                http.StatusInternalServerError,
×
86
                                errors.New("internal error"),
×
87
                        )
×
88
                }()
89
        } else if a.DisableLog != nil && a.DisableLog(c) {
10✔
90
                return
1✔
91
        }
1✔
92
        latency := time.Since(startTime)
9✔
93
        // We do not need more than 3 digit fraction
9✔
94
        if latency > time.Second {
10✔
95
                latency = latency.Round(time.Millisecond)
1✔
96
        } else if latency > time.Millisecond {
19✔
97
                latency = latency.Round(time.Microsecond)
9✔
98
        }
9✔
99
        code := c.Writer.Status()
9✔
100
        select {
9✔
101
        case <-ctx.Done():
×
102
                if errors.Is(ctx.Err(), context.Canceled) {
×
103
                        code = StatusClientClosedConnection
×
104
                }
×
105
        default:
9✔
106
        }
107
        logCtx["responsetime"] = latency.String()
9✔
108
        logCtx["status"] = c.Writer.Status()
9✔
109
        logCtx["byteswritten"] = c.Writer.Size()
9✔
110

9✔
111
        var logLevel logrus.Level = logrus.InfoLevel
9✔
112
        if code >= 500 {
11✔
113
                logLevel = logrus.ErrorLevel
2✔
114
        } else if code >= 400 {
19✔
115
                logLevel = logrus.WarnLevel
8✔
116
        }
8✔
117
        if len(c.Errors) > 0 {
16✔
118
                errs := c.Errors.Errors()
7✔
119
                var errMsg string
7✔
120
                if len(errs) == 1 {
14✔
121
                        errMsg = errs[0]
7✔
122
                } else {
8✔
123
                        for i, err := range errs {
2✔
124
                                errMsg = errMsg + fmt.Sprintf(
1✔
125
                                        "#%02d: %s\n", i+1, err,
1✔
126
                                )
1✔
127
                        }
1✔
128
                }
129
                logCtx["error"] = errMsg
7✔
130
        }
131
        log.FromContext(c.Request.Context()).
9✔
132
                WithFields(logCtx).
9✔
133
                Log(logLevel)
9✔
134
}
135

136
// Middleware implementsa gin compatible MiddlewareFunc
137
//
138
// NOTE: This accesslog middleware also implements the legacy requestlog
139
// middleware.
140
func (a AccessLogger) Middleware(c *gin.Context) {
9✔
141
        ctx := c.Request.Context()
9✔
142
        startTime := time.Now()
9✔
143
        ctx = log.WithContext(ctx, log.New(log.Ctx{}))
9✔
144
        ctx = withContext(ctx, &logContext{maxErrors: DefaultMaxErrors})
9✔
145
        c.Request = c.Request.WithContext(ctx)
9✔
146
        defer a.LogFunc(ctx, c, startTime)
9✔
147
        c.Next()
9✔
148
}
9✔
149

150
// Middleware provides accesslog middleware for the gin-gonic framework.
151
// This middleware will recover any panic from occurring in the API
152
// handler and log it to error level with panic and trace showing the panic
153
// message and traceback respectively.
154
// If an error status is returned in the response, the middleware tries
155
// to pop the topmost error from the gin.Context (c.Error) and puts it in
156
// the "error" context to the final log entry.
157
func Middleware() gin.HandlerFunc {
9✔
158
        return AccessLogger{ClientIPHook: getClientIPFromEnv()}.Middleware
9✔
159
}
9✔
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