Skip to content

Commit d55cbc4

Browse files
committed
Limit logging of warnings from plugins
1 parent 6a2066d commit d55cbc4

4 files changed

Lines changed: 76 additions & 9 deletions

File tree

internal/caddy/convert.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,25 @@ import (
1212
type Converter struct{}
1313

1414
func (c Converter) ConvertToCaddyConfig(store *store.Store) (interface{}, error) {
15-
cfg := converter.NewConfig()
15+
plugins := converter.Plugins(store.Options.PluginsOrder)
16+
17+
defer func() {
18+
for _, p := range plugins {
19+
if f, ok := p.(converter.Finalizer); ok {
20+
f.Finalize()
21+
}
22+
}
23+
}()
1624

17-
for _, p := range converter.Plugins(store.Options.PluginsOrder) {
25+
cfg := converter.NewConfig()
26+
for _, p := range plugins {
1827
if m, ok := p.(converter.GlobalMiddleware); ok {
1928
err := m.GlobalHandler(cfg, store)
2029
if err != nil {
2130
return cfg, err
2231
}
2332
}
2433
}
34+
2535
return cfg, nil
2636
}

internal/caddy/ingress/reverseproxy.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,24 @@ import (
88
"github.com/caddyserver/caddy/v2/caddyconfig"
99
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
1010
"github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy"
11+
"github.com/caddyserver/ingress/internal/controller"
1112
"github.com/caddyserver/ingress/pkg/converter"
1213
)
1314

14-
type ReverseProxyPlugin struct{}
15+
type ReverseProxyPlugin struct {
16+
diags controller.Diagnostics
17+
}
1518

1619
func (p ReverseProxyPlugin) IngressPlugin() converter.PluginInfo {
1720
return converter.PluginInfo{
1821
Name: "ingress.reverseproxy",
1922
// Should always go last by default
2023
Priority: -10,
21-
New: func() converter.Plugin { return new(ReverseProxyPlugin) },
24+
New: func() converter.Plugin {
25+
return &ReverseProxyPlugin{
26+
diags: make(controller.Diagnostics),
27+
}
28+
},
2229
}
2330
}
2431

@@ -32,22 +39,22 @@ func (p ReverseProxyPlugin) IngressHandler(input converter.IngressMiddlewareInpu
3239

3340
serviceRef := path.Backend.Service
3441
if serviceRef == nil {
35-
logger.Warnf("Ingress %s/%s uses a non-service backend, which is not supported, and will be ignored", ing.Namespace, ing.Name)
42+
p.diags.Warnf(logger, "Ingress %s/%s uses a non-service backend, which is not supported, and will be ignored", ing.Namespace, ing.Name)
3643
return input.Route, nil
3744
}
3845

3946
serviceName := fmt.Sprintf("%s/%s", ing.Namespace, serviceRef.Name)
4047
service := input.Store.Service(serviceName)
4148
if service == nil {
42-
logger.Warnf("Ingress %s/%s references unknown service %s and will be ignored", ing.Namespace, ing.Name, serviceRef.Name)
49+
p.diags.Warnf(logger, "Ingress %s/%s references unknown service %s and will be ignored", ing.Namespace, ing.Name, serviceRef.Name)
4350
return input.Route, nil
4451
}
4552

4653
var upstreams reverseproxy.UpstreamPool
4754
if service.Spec.Type == "ExternalName" {
4855
// Create a single upstream for type=ExternalName.
4956
if serviceRef.Port.Number == 0 {
50-
logger.Warnf("Ingress %s/%s references service %s with type=ExternalName and a named port, which is not supported, and will be ignored", ing.Namespace, ing.Name, service.Name)
57+
p.diags.Warnf(logger, "Ingress %s/%s references service %s with type=ExternalName and a named port, which is not supported, and will be ignored", ing.Namespace, ing.Name, service.Name)
5158
return input.Route, nil
5259
}
5360
upstreams = reverseproxy.UpstreamPool{
@@ -61,14 +68,14 @@ func (p ReverseProxyPlugin) IngressHandler(input converter.IngressMiddlewareInpu
6168
(serviceRef.Port.Name != "" && port.Name == serviceRef.Port.Name) {
6269
targetPort = int32(port.TargetPort.IntValue())
6370
if targetPort == 0 {
64-
logger.Warnf("Ingress %s/%s references service %s with a named target port, which is not supported, and will be ignored", ing.Namespace, ing.Name, service.Name)
71+
p.diags.Warnf(logger, "Ingress %s/%s references service %s with a named target port, which is not supported, and will be ignored", ing.Namespace, ing.Name, service.Name)
6572
return input.Route, nil
6673
}
6774
break
6875
}
6976
}
7077
if targetPort == 0 {
71-
logger.Warnf("Ingress %s/%s references an unknown port on service %s, and will be ignored", ing.Namespace, ing.Name, service.Name)
78+
p.diags.Warnf(logger, "Ingress %s/%s references an unknown port on service %s, and will be ignored", ing.Namespace, ing.Name, service.Name)
7279
return input.Route, nil
7380
}
7481

@@ -119,6 +126,10 @@ func (p ReverseProxyPlugin) IngressHandler(input converter.IngressMiddlewareInpu
119126
return input.Route, nil
120127
}
121128

129+
func (p ReverseProxyPlugin) Finalize() {
130+
p.diags.Gc()
131+
}
132+
122133
func formatDialAddr(host string, port int32) string {
123134
if strings.Contains(host, ":") {
124135
return fmt.Sprintf("[%s]:%d", host, port)
@@ -156,4 +167,5 @@ func init() {
156167
// Interface guards
157168
var (
158169
_ = converter.IngressMiddleware(ReverseProxyPlugin{})
170+
_ = converter.Finalizer(ReverseProxyPlugin{})
159171
)

internal/controller/diagnostics.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package controller
2+
3+
import (
4+
"fmt"
5+
"time"
6+
7+
"go.uber.org/zap"
8+
)
9+
10+
const diagnosticTimeout = 60 * time.Second
11+
12+
func getCutoff() time.Time {
13+
return time.Now().Add(diagnosticTimeout * -1)
14+
}
15+
16+
// Diagnostics is a simple map tracking when a diagnostic was last logged.
17+
type Diagnostics map[string]time.Time
18+
19+
// Gc removes entries from the map that have timed out.
20+
func (diags Diagnostics) Gc() {
21+
cutoff := getCutoff()
22+
for key, t := range diags {
23+
if t.Compare(cutoff) < 0 {
24+
delete(diags, key)
25+
}
26+
}
27+
}
28+
29+
// Warnf formats the the given message and checks if it is present in the map.
30+
// If not, the message will be logged at warning level and added to the map.
31+
func (diags Diagnostics) Warnf(logger *zap.SugaredLogger, template string, args ...any) bool {
32+
key := fmt.Sprintf(template, args...)
33+
if t, ok := diags[key]; ok && t.Compare(getCutoff()) >= 0 {
34+
return false
35+
}
36+
diags[key] = time.Now()
37+
logger.Warnf(template, args...)
38+
return true
39+
}

pkg/converter/converter.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ type IngressMiddleware interface {
3838
IngressHandler(input IngressMiddlewareInput) (*caddyhttp.Route, error)
3939
}
4040

41+
// Finalizer is an optional interface plugins can implement to perform finalization.
42+
// Note that Finalize may be called even if an earlier plugin caused an error.
43+
type Finalizer interface {
44+
Finalize()
45+
}
46+
4147
type Plugin interface {
4248
IngressPlugin() PluginInfo
4349
}

0 commit comments

Comments
 (0)