1616using  Serilog . Events ; 
1717using  Serilog . Formatting ; 
1818using  System ; 
19+ using  System . Collections . Generic ; 
1920using  System . IO ; 
2021using  System . Net . Sockets ; 
2122using  System . Text ; 
23+ using  System . Threading . Tasks ; 
24+ using  Serilog . Sinks . PeriodicBatching ; 
2225
2326namespace  Serilog . Sinks . Splunk 
2427{ 
2528    /// <summary> 
2629    /// A sink that logs to Splunk over UDP 
2730    /// </summary> 
28-     public  class  UdpSink  :  ILogEventSink ,   IDisposable 
31+     public  class  UdpSink  :  PeriodicBatchingSink 
2932    { 
3033        private  readonly  SplunkUdpSinkConnectionInfo  _connectionInfo ; 
3134        private  readonly  ITextFormatter  _formatter ; 
3235        private  Socket  _socket ; 
33-         private  bool  disposedValue  =  false ; 
3436
3537        /// <summary> 
3638        /// Creates an instance of the Splunk UDP Sink. 
@@ -48,51 +50,15 @@ public UdpSink(SplunkUdpSinkConnectionInfo connectionInfo, IFormatProvider forma
4850        /// </summary> 
4951        /// <param name="connectionInfo">Connection info used for connecting against Splunk.</param> 
5052        /// <param name="formatter">Custom formatter to use if you e.g. do not want to use the JsonFormatter.</param> 
51-         public  UdpSink ( SplunkUdpSinkConnectionInfo  connectionInfo ,  ITextFormatter  formatter ) 
53+         public  UdpSink ( SplunkUdpSinkConnectionInfo  connectionInfo ,  ITextFormatter  formatter )  
54+             :  base ( connectionInfo . BatchPostingLimit ,  connectionInfo . Period ,  connectionInfo . QueueSizeLimit ) 
5255        { 
5356            _connectionInfo  =  connectionInfo ; 
5457            _formatter  =  formatter ; 
5558            Connect ( ) ; 
5659        } 
57- 
58-         /// <inheritdoc/> 
59-         protected  virtual  void  Dispose ( bool  disposing ) 
60-         { 
61-             if  ( ! disposedValue ) 
62-             { 
63-                 if  ( disposing ) 
64-                 { 
65-                     DisposeSocket ( ) ; 
66-                 } 
67- 
68-                 disposedValue  =  true ; 
69-             } 
70-         } 
71- 
72-         /// <inheritdoc/> 
73-         public  void  Dispose ( ) 
74-         { 
75-             Dispose ( true ) ; 
76-         } 
77- 
78-         /// <inheritdoc/> 
79-         public  void  Emit ( LogEvent  logEvent ) 
80-         { 
81-             byte [ ]  data  =  Convert ( logEvent ) ; 
82- 
83-             try 
84-             { 
85-                 _socket . Send ( data ) ; 
86-             } 
87-             catch  ( SocketException ) 
88-             { 
89-                 // Try to reconnect and log 
90-                 DisposeSocket ( ) ; 
91-                 Connect ( ) ; 
92-                 _socket . Send ( data ) ; 
93-             } 
94-         } 
95- 
60+         
61+         
9662        private  byte [ ]  Convert ( LogEvent  logEvent ) 
9763        { 
9864            var  sb  =  new  StringBuilder ( ) ; 
@@ -107,13 +73,51 @@ private void Connect()
10773            _socket . Connect ( _connectionInfo . Host ,  _connectionInfo . Port ) ; 
10874        } 
10975
76+ 
77+         protected  override  void  Dispose ( bool  disposing ) 
78+         { 
79+             DisposeSocket ( ) ; 
80+ 
81+             base . Dispose ( true ) ; 
82+         } 
83+ 
11084        private  void  DisposeSocket ( ) 
11185        { 
11286            _socket ? . Close ( ) ; 
11387            _socket ? . Dispose ( ) ; 
11488            _socket  =  null ; 
11589        } 
11690
91+         /// <summary> 
92+         /// Emit a batch of log events, running to completion synchronously. 
93+         /// </summary> 
94+         /// <param name="events">The events to emit.</param> 
95+         /// <remarks> 
96+         /// Override either <see cref="M:Serilog.Sinks.PeriodicBatching.PeriodicBatchingSink.EmitBatch(System.Collections.Generic.IEnumerable{Serilog.Events.LogEvent})" /> 
97+         ///  or <see cref="M:Serilog.Sinks.PeriodicBatching.PeriodicBatchingSink.EmitBatchAsync(System.Collections.Generic.IEnumerable{Serilog.Events.LogEvent})" />, 
98+         /// not both. 
99+         /// </remarks> 
100+         protected  override  async  Task  EmitBatchAsync ( IEnumerable < LogEvent >  events ) 
101+         { 
102+             foreach  ( var  logEvent  in  events ) 
103+             { 
104+                 byte [ ]  data  =  Convert ( logEvent ) ; 
105+ 
106+                 try 
107+                 { 
108+                     _socket . Send ( data ) ; 
109+                 } 
110+                 catch  ( SocketException ) 
111+                 { 
112+                     // Try to reconnect and log 
113+                     DisposeSocket ( ) ; 
114+                     Connect ( ) ; 
115+                     _socket . Send ( data ) ; 
116+                 } 
117+             } 
118+         } 
119+ 
120+ 
117121        private  static SplunkJsonFormatter  CreateDefaultFormatter ( IFormatProvider  formatProvider ,  bool  renderTemplate ) 
118122        { 
119123            return  new  SplunkJsonFormatter ( renderTemplate ,  formatProvider ) ; 
0 commit comments