@@ -26,6 +26,16 @@ import (
2626const (
2727 maxTimeToWaitForShutdown = 30 * time .Second
2828 filePermission = 0o600
29+ // To conform to the rfc3164 spec the timestamp in the logs need to be formatted correctly.
30+ // Here are some examples of what the timestamp conversions look like.
31+ // Notice how if the day begins with a zero that the zero is replaced with an empty space.
32+
33+ // 2024-11-06T17:19:24+00:00 ---> Nov 6 17:19:24
34+ // 2024-11-16T17:19:24+00:00 ---> Nov 16 17:19:24
35+ timestampConversionExpression = `'EXPR(let timestamp = split(split(body, ">")[1], " ")[0]; ` +
36+ `let newTimestamp = timestamp matches "(\\d{4})-(\\d{2})-(0\\d{1})T(\\d{2}):(\\d{2}):(\\d{2}).*" ` +
37+ `? date(timestamp).Format("Jan 2 15:04:05") : date(timestamp).Format("Jan 02 15:04:05"); ` +
38+ `split(body, ">")[0] + ">" + newTimestamp + " " + split(body, " ", 2)[1])'`
2939)
3040
3141type (
@@ -193,9 +203,9 @@ func (oc *Collector) Close(ctx context.Context) error {
193203 oc .service .Shutdown ()
194204 oc .cancel ()
195205
196- settings := oc .config .Common
206+ settings := oc .config .Client . Backoff
197207 settings .MaxElapsedTime = maxTimeToWaitForShutdown
198- err := backoff .WaitUntil (ctx , oc . config . Common , func () error {
208+ err := backoff .WaitUntil (ctx , settings , func () error {
199209 if oc .service .GetState () == otelcol .StateClosed {
200210 return nil
201211 }
@@ -243,7 +253,7 @@ func (oc *Collector) handleNginxConfigUpdate(ctx context.Context, msg *bus.Messa
243253 return
244254 }
245255
246- reloadCollector := oc .checkForNewNginxReceivers (nginxConfigContext )
256+ reloadCollector := oc .checkForNewReceivers (nginxConfigContext )
247257
248258 if reloadCollector {
249259 slog .InfoContext (ctx , "Reloading OTel collector config" )
@@ -368,7 +378,7 @@ func (oc *Collector) restartCollector(ctx context.Context) {
368378 }
369379}
370380
371- func (oc * Collector ) checkForNewNginxReceivers (nginxConfigContext * model.NginxConfigContext ) bool {
381+ func (oc * Collector ) checkForNewReceivers (nginxConfigContext * model.NginxConfigContext ) bool {
372382 nginxReceiverFound , reloadCollector := oc .updateExistingNginxPlusReceiver (nginxConfigContext )
373383
374384 if ! nginxReceiverFound && nginxConfigContext .PlusAPI .URL != "" {
@@ -406,6 +416,11 @@ func (oc *Collector) checkForNewNginxReceivers(nginxConfigContext *model.NginxCo
406416 }
407417 }
408418
419+ tcplogReceiversFound := oc .updateTcplogReceivers (nginxConfigContext )
420+ if tcplogReceiversFound {
421+ reloadCollector = true
422+ }
423+
409424 return reloadCollector
410425}
411426
@@ -476,6 +491,110 @@ func (oc *Collector) updateExistingNginxOSSReceiver(
476491 return nginxReceiverFound , reloadCollector
477492}
478493
494+ func (oc * Collector ) updateTcplogReceivers (nginxConfigContext * model.NginxConfigContext ) bool {
495+ newTcplogReceiverAdded := false
496+ if nginxConfigContext .NAPSysLogServers != nil {
497+ napLoop:
498+ for _ , napSysLogServer := range nginxConfigContext .NAPSysLogServers {
499+ if oc .doesTcplogReceiverAlreadyExist (napSysLogServer ) {
500+ continue napLoop
501+ }
502+
503+ oc .config .Collector .Receivers .TcplogReceivers = append (
504+ oc .config .Collector .Receivers .TcplogReceivers ,
505+ config.TcplogReceiver {
506+ ListenAddress : napSysLogServer ,
507+ Operators : []config.Operator {
508+ {
509+ Type : "add" ,
510+ Fields : map [string ]string {
511+ "field" : "body" ,
512+ "value" : timestampConversionExpression ,
513+ },
514+ },
515+ {
516+ Type : "syslog_parser" ,
517+ Fields : map [string ]string {
518+ "protocol" : "rfc3164" ,
519+ },
520+ },
521+ {
522+ Type : "remove" ,
523+ Fields : map [string ]string {
524+ "field" : "attributes.message" ,
525+ },
526+ },
527+ {
528+ Type : "add" ,
529+ Fields : map [string ]string {
530+ "field" : "resource[\" instance.id\" ]" ,
531+ "value" : nginxConfigContext .InstanceID ,
532+ },
533+ },
534+ },
535+ },
536+ )
537+
538+ newTcplogReceiverAdded = true
539+ }
540+ }
541+
542+ tcplogReceiverDeleted := oc .areNapReceiversDeleted (nginxConfigContext )
543+
544+ return newTcplogReceiverAdded || tcplogReceiverDeleted
545+ }
546+
547+ func (oc * Collector ) areNapReceiversDeleted (nginxConfigContext * model.NginxConfigContext ) bool {
548+ listenAddressesToBeDeleted := oc .getConfigDeletedNapReceivers (nginxConfigContext )
549+ if len (listenAddressesToBeDeleted ) != 0 {
550+ oc .deleteNapReceivers (listenAddressesToBeDeleted )
551+ return true
552+ }
553+
554+ return false
555+ }
556+
557+ func (oc * Collector ) deleteNapReceivers (listenAddressesToBeDeleted map [string ]bool ) {
558+ filteredReceivers := (oc .config .Collector .Receivers .TcplogReceivers )[:0 ]
559+ for _ , receiver := range oc .config .Collector .Receivers .TcplogReceivers {
560+ if ! listenAddressesToBeDeleted [receiver .ListenAddress ] {
561+ filteredReceivers = append (filteredReceivers , receiver )
562+ }
563+ }
564+ oc .config .Collector .Receivers .TcplogReceivers = filteredReceivers
565+ }
566+
567+ func (oc * Collector ) getConfigDeletedNapReceivers (nginxConfigContext * model.NginxConfigContext ) map [string ]bool {
568+ elements := make (map [string ]bool )
569+
570+ for _ , tcplogReceiver := range oc .config .Collector .Receivers .TcplogReceivers {
571+ elements [tcplogReceiver .ListenAddress ] = true
572+ }
573+
574+ if nginxConfigContext .NAPSysLogServers != nil {
575+ addressesToDelete := make (map [string ]bool )
576+ for _ , napAddress := range nginxConfigContext .NAPSysLogServers {
577+ if ! elements [napAddress ] {
578+ addressesToDelete [napAddress ] = true
579+ }
580+ }
581+
582+ return addressesToDelete
583+ }
584+
585+ return elements
586+ }
587+
588+ func (oc * Collector ) doesTcplogReceiverAlreadyExist (listenAddress string ) bool {
589+ for _ , tcplogReceiver := range oc .config .Collector .Receivers .TcplogReceivers {
590+ if listenAddress == tcplogReceiver .ListenAddress {
591+ return true
592+ }
593+ }
594+
595+ return false
596+ }
597+
479598// nolint: revive
480599func (oc * Collector ) updateResourceAttributes (
481600 attributesToAdd []config.ResourceAttribute ,
0 commit comments