Skip to content

Commit ca33637

Browse files
committed
introduce AppLogEmitterFactory
1 parent 2a9d7d4 commit ca33637

12 files changed

Lines changed: 153 additions & 35 deletions

src/cmd/syslog-agent/app/syslog_agent.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ func NewSyslogAgent(
5656
cfg Config,
5757
m Metrics,
5858
l *log.Logger,
59+
factory syslog.AppLogEmitterFactory,
5960
) *SyslogAgent {
6061
ingressTLSConfig, err := loggregator.NewIngressTLSConfig(
6162
cfg.GRPC.CAFile,
@@ -87,7 +88,7 @@ func NewSyslogAgent(
8788
timeoutwaitgroup.New(time.Minute),
8889
writerFactory,
8990
m,
90-
syslog.WithAppLogEmitter(syslog.NewAppLogEmitter(logClient, "syslog_agent")),
91+
syslog.WithAppLogEmitter(factory.NewAppLogEmitter(logClient, "syslog_agent")),
9192
)
9293

9394
var cacheClient *cache.CacheClient
@@ -108,7 +109,7 @@ func NewSyslogAgent(
108109
m,
109110
cfg.WarnOnInvalidDrains,
110111
l,
111-
syslog.NewAppLogEmitter(logClient, "syslog_agent"),
112+
factory.NewAppLogEmitter(logClient, "syslog_agent"),
112113
)
113114
cupsFetcher = bindings.NewDrainParamParser(cupsFetcher, cfg.DefaultDrainMetadata)
114115
}

src/cmd/syslog-agent/app/syslog_agent_mtls_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package app_test
22

33
import (
4+
"code.cloudfoundry.org/loggregator-agent-release/src/pkg/egress/syslog"
45
"context"
56
"encoding/json"
67
"fmt"
@@ -41,6 +42,8 @@ var _ = Describe("SyslogAgent with mTLS", func() {
4142
agentMetrics *metricsHelpers.SpyMetricsRegistry
4243
agentLogr *log.Logger
4344
agent *app.SyslogAgent
45+
46+
factory syslog.AppLogEmitterFactory
4447
)
4548

4649
BeforeEach(func() {
@@ -141,6 +144,9 @@ var _ = Describe("SyslogAgent with mTLS", func() {
141144
}
142145
agentMetrics = metricsHelpers.NewMetricsRegistry()
143146
agentLogr = log.New(GinkgoWriter, "", log.LstdFlags)
147+
148+
defaultFactory := syslog.NewDefaultAppLogEmitterFactory()
149+
factory = &defaultFactory
144150
})
145151

146152
JustBeforeEach(func() {
@@ -154,7 +160,7 @@ var _ = Describe("SyslogAgent with mTLS", func() {
154160
agentCfg.Cache.PollingInterval = 10 * time.Millisecond
155161
}
156162

157-
agent = app.NewSyslogAgent(agentCfg, agentMetrics, agentLogr)
163+
agent = app.NewSyslogAgent(agentCfg, agentMetrics, agentLogr, factory)
158164
go agent.Run()
159165
})
160166

src/cmd/syslog-agent/app/syslog_agent_test.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package app_test
22

33
import (
4+
"code.cloudfoundry.org/loggregator-agent-release/src/pkg/egress/syslog"
45
"context"
56
"crypto/tls"
67
"fmt"
@@ -48,6 +49,8 @@ var _ = Describe("SyslogAgent", func() {
4849
agentMetrics *metricsHelpers.SpyMetricsRegistry
4950
agentLogr *log.Logger
5051
agent *app.SyslogAgent
52+
53+
factory syslog.AppLogEmitterFactory
5154
)
5255

5356
BeforeEach(func() {
@@ -121,6 +124,9 @@ var _ = Describe("SyslogAgent", func() {
121124
}
122125
agentMetrics = metricsHelpers.NewMetricsRegistry()
123126
agentLogr = log.New(GinkgoWriter, "", log.LstdFlags)
127+
128+
defaultFactory := syslog.NewDefaultAppLogEmitterFactory()
129+
factory = &defaultFactory
124130
})
125131

126132
JustBeforeEach(func() {
@@ -134,7 +140,7 @@ var _ = Describe("SyslogAgent", func() {
134140
agentCfg.Cache.PollingInterval = 10 * time.Millisecond
135141
}
136142

137-
agent = app.NewSyslogAgent(agentCfg, agentMetrics, agentLogr)
143+
agent = app.NewSyslogAgent(agentCfg, agentMetrics, agentLogr, factory)
138144
go agent.Run()
139145
})
140146

@@ -238,6 +244,14 @@ var _ = Describe("SyslogAgent", func() {
238244
Eventually(agentMetrics.GetDebugMetricsEnabled).Should(BeFalse())
239245
})
240246

247+
It("configures appLogEmitter", func() {
248+
spyFactory := testhelper.SpyAppLogEmitterFactory{}
249+
app.NewSyslogAgent(agentCfg, agentMetrics, agentLogr, &spyFactory)
250+
251+
Expect(spyFactory.SourceIndex()).Should(Equal("syslog_agent"))
252+
Expect(spyFactory.LogClient()).ShouldNot(BeNil())
253+
})
254+
241255
Context("when debug configuration is enabled", func() {
242256
BeforeEach(func() {
243257
agentCfg.MetricsServer.DebugMetrics = true
@@ -423,7 +437,7 @@ var _ = Describe("SyslogAgent", func() {
423437
cfgCopy.GRPC.KeyFile = "invalid"
424438

425439
msg := `failed to configure client TLS: "failed to load keypair: open invalid: no such file or directory"`
426-
Expect(func() { app.NewSyslogAgent(cfgCopy, agentMetrics, agentLogr) }).To(PanicWith(msg))
440+
Expect(func() { app.NewSyslogAgent(cfgCopy, agentMetrics, agentLogr, factory) }).To(PanicWith(msg))
427441
})
428442
})
429443
})

src/cmd/syslog-agent/main.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"code.cloudfoundry.org/loggregator-agent-release/src/pkg/egress/syslog"
45
"log"
56
_ "net/http/pprof" //nolint:gosec
67
"os"
@@ -33,5 +34,7 @@ func main() {
3334
),
3435
)
3536

36-
app.NewSyslogAgent(cfg, m, logger).Run()
37+
factory := syslog.NewDefaultAppLogEmitterFactory()
38+
39+
app.NewSyslogAgent(cfg, m, logger, &factory).Run()
3740
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package testhelper
2+
3+
import "code.cloudfoundry.org/loggregator-agent-release/src/pkg/egress/syslog"
4+
5+
type SpyAppLogEmitter struct {
6+
}
7+
8+
func (emitter *SpyAppLogEmitter) EmitLog(appID string, message string) {
9+
10+
}
11+
12+
func NewSpyAppEmitter() SpyAppLogEmitter {
13+
return SpyAppLogEmitter{}
14+
}
15+
16+
type SpyAppLogEmitterFactory struct {
17+
logClient syslog.LogClient
18+
sourceIndex string
19+
}
20+
21+
func (factory *SpyAppLogEmitterFactory) LogClient() syslog.LogClient {
22+
return factory.logClient
23+
}
24+
25+
func (factory *SpyAppLogEmitterFactory) SourceIndex() string {
26+
return factory.sourceIndex
27+
}
28+
29+
func (factory *SpyAppLogEmitterFactory) NewAppLogEmitter(logClient syslog.LogClient, sourceIndex string) syslog.AppLogEmitter {
30+
factory.logClient = logClient
31+
factory.sourceIndex = sourceIndex
32+
emitter := NewSpyAppEmitter()
33+
return &emitter
34+
}

src/pkg/egress/syslog/app_log_emitter.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,19 @@ type LogClient interface {
99
EmitLog(message string, opts ...loggregator.EmitLogOption)
1010
}
1111

12-
type AppLogEmitter struct {
12+
// AppLogEmitter abstracts the sending of a log to the application log stream.
13+
type AppLogEmitter interface {
14+
EmitLog(appID string, message string)
15+
}
16+
17+
// DefaultAppLogEmitter is an implementation of AppLogEmitter which sends logs to an instance of a LogClient
18+
type DefaultAppLogEmitter struct {
1319
logClient LogClient
1420
sourceIndex string
1521
}
1622

1723
// EmitLog writes a message in the application log stream using a LogClient.
18-
func (appLogEmitter *AppLogEmitter) EmitLog(appID string, message string) {
24+
func (appLogEmitter *DefaultAppLogEmitter) EmitLog(appID string, message string) {
1925
if appLogEmitter.logClient == nil || appID == "" {
2026
return
2127
}
@@ -31,10 +37,23 @@ func (appLogEmitter *AppLogEmitter) EmitLog(appID string, message string) {
3137
appLogEmitter.logClient.EmitLog(message, option)
3238
}
3339

34-
// NewAppLogEmitter creates a new AppLogEmitter.
35-
func NewAppLogEmitter(logClient LogClient, sourceIndex string) AppLogEmitter {
36-
return AppLogEmitter{
40+
// AppLogEmitterFactory is used to create new instances of AppLogEmitter
41+
type AppLogEmitterFactory interface {
42+
NewAppLogEmitter(logClient LogClient, sourceIndex string) AppLogEmitter
43+
}
44+
45+
// DefaultAppLogEmitterFactory implementation of AppLogEmitterFactory to produce DefaultAppLogEmitter.
46+
type DefaultAppLogEmitterFactory struct {
47+
}
48+
49+
// NewAppLogEmitter creates a new DefaultAppLogEmitter.
50+
func (factory *DefaultAppLogEmitterFactory) NewAppLogEmitter(logClient LogClient, sourceIndex string) AppLogEmitter {
51+
return &DefaultAppLogEmitter{
3752
logClient: logClient,
3853
sourceIndex: sourceIndex,
3954
}
4055
}
56+
57+
func NewDefaultAppLogEmitterFactory() DefaultAppLogEmitterFactory {
58+
return DefaultAppLogEmitterFactory{}
59+
}

src/pkg/egress/syslog/app_log_emitter_test.go

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ import (
88
)
99

1010
var _ = Describe("Loggregator Emitter", func() {
11-
Describe("EmitLog()", func() {
11+
Describe("DefaultAppLogEmitter", func() {
1212
It("emits a log message", func() {
1313
logClient := testhelper.NewSpyLogClient()
14-
emitter := syslog.NewAppLogEmitter(logClient, "0")
14+
factory := syslog.NewDefaultAppLogEmitterFactory()
15+
emitter := factory.NewAppLogEmitter(logClient, "0")
1516

1617
emitter.EmitLog("app-id", "some-message")
1718

@@ -29,7 +30,8 @@ var _ = Describe("Loggregator Emitter", func() {
2930

3031
It("does not emit a log message if the appID is empty", func() {
3132
logClient := testhelper.NewSpyLogClient()
32-
emitter := syslog.NewAppLogEmitter(logClient, "0")
33+
factory := syslog.NewDefaultAppLogEmitterFactory()
34+
emitter := factory.NewAppLogEmitter(logClient, "0")
3335

3436
emitter.EmitLog("", "some-message")
3537

@@ -42,4 +44,29 @@ var _ = Describe("Loggregator Emitter", func() {
4244
Expect(sourceTypes).ToNot(HaveKey("SYS"))
4345
})
4446
})
47+
48+
Describe("DefaultAppLogEmitterFactory", func() {
49+
It("produces a DefaultAppLogEmitter", func() {
50+
factory := syslog.NewDefaultAppLogEmitterFactory()
51+
logClient := testhelper.NewSpyLogClient()
52+
sourceIndex := "test-index"
53+
54+
emitter := factory.NewAppLogEmitter(logClient, sourceIndex)
55+
emitter.EmitLog("app-id", "some-message")
56+
57+
messages := logClient.Message()
58+
appIDs := logClient.AppID()
59+
sourceTypes := logClient.SourceType()
60+
sourceInstance := logClient.SourceInstance()
61+
Expect(messages).To(HaveLen(2))
62+
Expect(messages[0]).To(Equal("some-message"))
63+
Expect(messages[1]).To(Equal("some-message"))
64+
Expect(appIDs[0]).To(Equal("app-id"))
65+
Expect(appIDs[1]).To(Equal("app-id"))
66+
Expect(sourceTypes).To(HaveKey("LGR"))
67+
Expect(sourceTypes).To(HaveKey("SYS"))
68+
Expect(sourceInstance).To(HaveKey(""))
69+
Expect(sourceInstance).To(HaveKey("test-index"))
70+
})
71+
})
4572
})

src/pkg/egress/syslog/retry_writer_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package syslog_test
22

33
import (
4+
"code.cloudfoundry.org/loggregator-agent-release/src/internal/testhelper"
45
"errors"
56
"net/url"
67
"sync/atomic"
@@ -175,11 +176,12 @@ func buildRetryWriter(
175176
maxRetries int,
176177
delayMultiplier time.Duration,
177178
) (egress.WriteCloser, error) {
179+
emitter := testhelper.NewSpyAppEmitter()
178180
return syslog.NewRetryWriter(
179181
urlBinding,
180182
syslog.RetryDuration(buildDelay(delayMultiplier)),
181183
maxRetries,
182184
w,
183-
syslog.AppLogEmitter{},
185+
&emitter,
184186
)
185187
}

src/pkg/egress/syslog/syslog_connector.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,9 @@ func (w *SyslogConnector) Connect(ctx context.Context, b Binding) (egress.Writer
122122
w.droppedMetric.Add(float64(missed))
123123
drainDroppedMetric.Add(float64(missed))
124124

125-
w.appLogEmitter.EmitLog(b.AppId, fmt.Sprintf("%d messages lost for application %s in user provided syslog drain with url %s", missed, b.AppId, anonymousUrl.String()))
125+
if w.appLogEmitter != nil {
126+
w.appLogEmitter.EmitLog(b.AppId, fmt.Sprintf("%d messages lost for application %s in user provided syslog drain with url %s", missed, b.AppId, anonymousUrl.String()))
127+
}
126128
w.emitStandardOutErrorLog(b.AppId, urlBinding.Scheme(), anonymousUrl.String(), missed)
127129
}), w.wg)
128130

src/pkg/egress/syslog/syslog_connector_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,13 @@ var _ = Describe("SyslogConnector", func() {
174174

175175
It("emits a LGR and SYS log to the log client about logs that have been dropped", func() {
176176
logClient := testhelper.NewSpyLogClient()
177+
factory := syslog.NewDefaultAppLogEmitterFactory()
177178
connector := syslog.NewSyslogConnector(
178179
true,
179180
spyWaitGroup,
180181
writerFactory,
181182
sm,
182-
syslog.WithAppLogEmitter(syslog.NewAppLogEmitter(logClient, "3")),
183+
syslog.WithAppLogEmitter(factory.NewAppLogEmitter(logClient, "3")),
183184
)
184185

185186
binding := syslog.Binding{AppId: "app-id",
@@ -216,12 +217,13 @@ var _ = Describe("SyslogConnector", func() {
216217

217218
It("doesn't emit LGR and SYS log to the log client about aggregate drains drops", func() {
218219
logClient := testhelper.NewSpyLogClient()
220+
factory := syslog.NewDefaultAppLogEmitterFactory()
219221
connector := syslog.NewSyslogConnector(
220222
true,
221223
spyWaitGroup,
222224
writerFactory,
223225
sm,
224-
syslog.WithAppLogEmitter(syslog.NewAppLogEmitter(logClient, "3")),
226+
syslog.WithAppLogEmitter(factory.NewAppLogEmitter(logClient, "3")),
225227
)
226228

227229
binding := syslog.Binding{Drain: syslog.Drain{Url: "dropping://"}}

0 commit comments

Comments
 (0)