@@ -7,22 +7,29 @@ package logs
77import (
88 "context"
99 "fmt"
10+ "strings"
11+ "sync"
1012
1113 "github.com/go-logr/logr"
1214 "github.com/go-logr/stdr"
15+ "go.uber.org/atomic"
1316
17+ "github.com/ARM-software/golang-utils/utils/collection"
1418 "github.com/ARM-software/golang-utils/utils/commonerrors"
1519 "github.com/ARM-software/golang-utils/utils/reflection"
1620)
1721
1822const (
19- KeyLogSource = "source"
20- KeyLoggerSource = "logger-source"
23+ KeyLogSource = "source"
24+ KeyLoggerSource = "logger-source"
25+ keyloggerSources = "logger-sources"
2126)
2227
2328type logrLogger struct {
2429 logger logr.Logger
2530 closeFunc func () error
31+ source * atomic.String
32+ logSource * atomic.String
2633}
2734
2835func (l * logrLogger ) Close () error {
@@ -36,18 +43,28 @@ func (l *logrLogger) Check() error {
3643 return nil
3744}
3845
46+ // SetLogSource will not overwrite the source if already defined
3947func (l * logrLogger ) SetLogSource (source string ) error {
4048 if reflection .IsEmpty (source ) {
4149 return commonerrors .ErrNoLogSource
4250 }
51+ if strings .EqualFold (source , l .logSource .Load ()) {
52+ return nil
53+ }
54+ l .logSource .Store (source )
4355 l .logger = l .logger .WithValues (KeyLogSource , source )
4456 return nil
4557}
4658
59+ // SetLoggerSource will not overwrite the source if already defined
4760func (l * logrLogger ) SetLoggerSource (source string ) error {
4861 if reflection .IsEmpty (source ) {
4962 return commonerrors .ErrNoLoggerSource
5063 }
64+ if strings .EqualFold (source , l .source .Load ()) {
65+ return nil
66+ }
67+ l .source .Store (source )
5168 l .logger = l .logger .WithName (source ).WithValues (KeyLoggerSource , source )
5269 return nil
5370}
@@ -76,7 +93,12 @@ func NewLogrLogger(logrImpl logr.Logger, loggerSource string) (Loggers, error) {
7693
7794// NewLogrLoggerWithClose creates loggers based on a logr implementation (https://github.com/go-logr/logr)
7895func NewLogrLoggerWithClose (logrImpl logr.Logger , loggerSource string , closeFunc func () error ) (loggers Loggers , err error ) {
79- loggers = & logrLogger {logger : logrImpl , closeFunc : closeFunc }
96+ loggers = & logrLogger {
97+ logger : logrImpl ,
98+ closeFunc : closeFunc ,
99+ source : atomic .NewString ("" ),
100+ logSource : atomic .NewString ("" ),
101+ }
80102 err = loggers .SetLoggerSource (loggerSource )
81103 return
82104}
@@ -131,13 +153,13 @@ func (s *plainLoggersSinkAdapter) Error(err error, msg string, keysAndValues ...
131153 }
132154}
133155
134- func (s * plainLoggersSinkAdapter ) WithValues (keysAndValues ... any ) logr.LogSink {
156+ func (s * plainLoggersSinkAdapter ) WithValues (_ ... any ) logr.LogSink {
135157 return & plainLoggersSinkAdapter {underlying : s .underlying }
136158}
137159
138160func (s * plainLoggersSinkAdapter ) WithName (name string ) logr.LogSink {
139161 if s .underlying != nil {
140- _ = s .underlying .SetLogSource (name )
162+ _ = s .underlying .SetLoggerSource (name )
141163 }
142164 return & plainLoggersSinkAdapter {underlying : s .underlying }
143165}
@@ -151,6 +173,7 @@ func NewPlainLoggersSink(logger Loggers) logr.LogSink {
151173type loggersLogSinkAdapter struct {
152174 stdOut logr.LogSink
153175 stdErr logr.LogSink
176+ values sync.Map
154177 underlying Loggers
155178}
156179
@@ -172,23 +195,106 @@ func (l *loggersLogSinkAdapter) Error(err error, msg string, keysAndValues ...an
172195 l .stdErr .Error (err , msg , keysAndValues ... )
173196}
174197
198+ // WithValues will not overwrite already defined values.
175199func (l * loggersLogSinkAdapter ) WithValues (keysAndValues ... any ) logr.LogSink {
176- return & loggersLogSinkAdapter {
177- stdOut : l .stdOut .WithValues (keysAndValues ... ),
178- stdErr : l .stdErr .WithValues (keysAndValues ... ),
200+ sink := & loggersLogSinkAdapter {
201+ stdOut : l .stdOut ,
202+ stdErr : l .stdErr ,
203+ values : sync.Map {},
179204 underlying : l .underlying ,
180205 }
206+ l .transferValues (sink )
207+ sink .withValues (keysAndValues ... )
208+ return sink
181209}
182210
183- func (l * loggersLogSinkAdapter ) WithName (name string ) logr.LogSink {
211+ func (l * loggersLogSinkAdapter ) transferValues (sink * loggersLogSinkAdapter ) {
212+ if sink == nil {
213+ return
214+ }
215+ l .values .Range (func (k , v any ) bool {
216+ return sink .recordValue (k , v )
217+ })
218+ }
219+
220+ func (l * loggersLogSinkAdapter ) withValues (keysAndValues ... any ) {
221+ if len (keysAndValues )% 2 != 0 {
222+ return
223+ }
224+ for i := 0 ; i < len (keysAndValues ); i += 2 {
225+ k := keysAndValues [i ]
226+ v := keysAndValues [i + 1 ]
227+ _ , _ = l .values .LoadOrStore (k , v )
228+ }
229+ }
230+
231+ func (l * loggersLogSinkAdapter ) recordValue (k , v any ) bool {
232+ l .values .Store (k , v )
233+ return true
234+ }
235+
236+ func (l * loggersLogSinkAdapter ) recordName (name string ) {
237+ if reflection .IsEmpty (name ) {
238+ return
239+ }
184240 if l .underlying != nil {
185- _ = l .underlying .SetLogSource (name )
241+ _ = l .underlying .SetLoggerSource (name )
186242 }
187- return & loggersLogSinkAdapter {
188- stdOut : l .stdOut .WithName (name ),
189- stdErr : l .stdErr .WithName (name ),
190- underlying : l .underlying ,
243+ if l .hasName (name ) {
244+ return
245+ }
246+ namesAny , ok := l .values .Load (keyloggerSources )
247+ var names []string
248+ if ok {
249+ namesC , ok := namesAny .([]string )
250+ if ! ok {
251+ return
252+ }
253+ names = namesC
254+ }
255+ names = append (names , name )
256+ _ = l .recordValue (keyloggerSources , names )
257+ }
258+
259+ func (l * loggersLogSinkAdapter ) hasName (name string ) (found bool ) {
260+ if reflection .IsEmpty (name ) {
261+ return
262+ }
263+ namesAny , ok := l .values .Load (keyloggerSources )
264+ if ! ok {
265+ return
266+ }
267+ names , ok := namesAny .([]string )
268+ if ! ok {
269+ return
191270 }
271+ _ , found = collection .FindInSlice (false , names , name )
272+ return
273+ }
274+
275+ func (l * loggersLogSinkAdapter ) WithName (name string ) logr.LogSink {
276+ setName := ! l .hasName (name )
277+ var sink * loggersLogSinkAdapter
278+ if setName {
279+ sink = & loggersLogSinkAdapter {
280+ stdOut : l .stdOut .WithName (name ),
281+ stdErr : l .stdErr .WithName (name ),
282+ values : sync.Map {},
283+ underlying : l .underlying ,
284+ }
285+ } else {
286+ sink = & loggersLogSinkAdapter {
287+ stdOut : l .stdOut ,
288+ stdErr : l .stdErr ,
289+ values : sync.Map {},
290+ underlying : l .underlying ,
291+ }
292+ }
293+
294+ l .transferValues (sink )
295+ sink .recordName (name )
296+
297+ return sink
192298}
193299
194300func NewLoggersLogSink (logger Loggers ) logr.LogSink {
0 commit comments