~ifolder-dev/simias/trunk-packaging

« back to all changes in this revision

Viewing changes to src/core/Simias.log4net/src/Appender/.svn/text-base/UdpAppender.cs.svn-base

  • Committer: Jorge O. Castro
  • Date: 2007-12-03 06:56:46 UTC
  • Revision ID: jorge@ubuntu.com-20071203065646-mupcnjcwgm5mnhyt
* Remove a bunch of .svn directories we no longer need.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#region Copyright & License
2
 
//
3
 
// Copyright 2001-2005 The Apache Software Foundation
4
 
//
5
 
// Licensed under the Apache License, Version 2.0 (the "License");
6
 
// you may not use this file except in compliance with the License.
7
 
// You may obtain a copy of the License at
8
 
//
9
 
// http://www.apache.org/licenses/LICENSE-2.0
10
 
//
11
 
// Unless required by applicable law or agreed to in writing, software
12
 
// distributed under the License is distributed on an "AS IS" BASIS,
13
 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 
// See the License for the specific language governing permissions and
15
 
// limitations under the License.
16
 
//
17
 
#endregion
18
 
 
19
 
using System;
20
 
using System.Globalization;
21
 
using System.Net;
22
 
using System.Net.Sockets;
23
 
using System.Text;
24
 
 
25
 
using log4net.Layout;
26
 
using log4net.Core;
27
 
using log4net.Util;
28
 
 
29
 
namespace log4net.Appender 
30
 
{
31
 
        /// <summary>
32
 
        /// Sends logging events as connectionless UDP datagrams to a remote host or a 
33
 
        /// multicast group using an <see cref="UdpClient" />.
34
 
        /// </summary>
35
 
        /// <remarks>
36
 
        /// <para>
37
 
        /// UDP guarantees neither that messages arrive, nor that they arrive in the correct order.
38
 
        /// </para>
39
 
        /// <para>
40
 
        /// To view the logging results, a custom application can be developed that listens for logging 
41
 
        /// events.
42
 
        /// </para>
43
 
        /// <para>
44
 
        /// When decoding events send via this appender remember to use the same encoding
45
 
        /// to decode the events as was used to send the events. See the <see cref="Encoding"/>
46
 
        /// property to specify the encoding to use.
47
 
        /// </para>
48
 
        /// </remarks>
49
 
        /// <example>
50
 
        /// This example shows how to log receive logging events that are sent 
51
 
        /// on IP address 244.0.0.1 and port 8080 to the console. The event is 
52
 
        /// encoded in the packet as a unicode string and it is decoded as such. 
53
 
        /// <code lang="C#">
54
 
        /// IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
55
 
        /// UdpClient udpClient;
56
 
        /// byte[] buffer;
57
 
        /// string loggingEvent;
58
 
        /// 
59
 
        /// try 
60
 
        /// {
61
 
        ///     udpClient = new UdpClient(8080);
62
 
        ///     
63
 
        ///     while(true) 
64
 
        ///     {
65
 
        ///         buffer = udpClient.Receive(ref remoteEndPoint);
66
 
        ///         loggingEvent = System.Text.Encoding.Unicode.GetString(buffer);
67
 
        ///         Console.WriteLine(loggingEvent);
68
 
        ///     }
69
 
        /// } 
70
 
        /// catch(Exception e) 
71
 
        /// {
72
 
        ///     Console.WriteLine(e.ToString());
73
 
        /// }
74
 
        /// </code>
75
 
        /// <code lang="Visual Basic">
76
 
        /// Dim remoteEndPoint as IPEndPoint
77
 
        /// Dim udpClient as UdpClient
78
 
        /// Dim buffer as Byte()
79
 
        /// Dim loggingEvent as String
80
 
        /// 
81
 
        /// Try 
82
 
        ///     remoteEndPoint = new IPEndPoint(IPAddress.Any, 0)
83
 
        ///     udpClient = new UdpClient(8080)
84
 
        ///
85
 
        ///     While True
86
 
        ///         buffer = udpClient.Receive(ByRef remoteEndPoint)
87
 
        ///         loggingEvent = System.Text.Encoding.Unicode.GetString(buffer)
88
 
        ///         Console.WriteLine(loggingEvent)
89
 
        ///     Wend
90
 
        /// Catch e As Exception
91
 
        ///     Console.WriteLine(e.ToString())
92
 
        /// End Try
93
 
        /// </code>
94
 
        /// <para>
95
 
        /// An example configuration section to log information using this appender to the 
96
 
        /// IP 224.0.0.1 on port 8080:
97
 
        /// </para>
98
 
        /// <code lang="XML" escaped="true">
99
 
        /// <appender name="UdpAppender" type="log4net.Appender.UdpAppender">
100
 
        ///     <remoteAddress value="224.0.0.1" />
101
 
        ///     <remotePort value="8080" />
102
 
        ///     <layout type="log4net.Layout.PatternLayout" value="%-5level %logger [%ndc] - %message%newline" />
103
 
        /// </appender>
104
 
        /// </code>
105
 
        /// </example>
106
 
        /// <author>Gert Driesen</author>
107
 
        /// <author>Nicko Cadell</author>
108
 
        public class UdpAppender : AppenderSkeleton
109
 
        {
110
 
                #region Public Instance Constructors
111
 
 
112
 
                /// <summary>
113
 
                /// Initializes a new instance of the <see cref="UdpAppender" /> class.
114
 
                /// </summary>
115
 
                /// <remarks>
116
 
                /// The default constructor initializes all fields to their default values.
117
 
                /// </remarks>
118
 
                public UdpAppender() 
119
 
                {
120
 
                }
121
 
 
122
 
                #endregion Public Instance Constructors
123
 
 
124
 
                #region Public Instance Properties
125
 
 
126
 
                /// <summary>
127
 
                /// Gets or sets the IP address of the remote host or multicast group to which
128
 
                /// the underlying <see cref="UdpClient" /> should sent the logging event.
129
 
                /// </summary>
130
 
                /// <value>
131
 
                /// The IP address of the remote host or multicast group to which the logging event 
132
 
                /// will be sent.
133
 
                /// </value>
134
 
                /// <remarks>
135
 
                /// <para>
136
 
                /// Multicast addresses are identified by IP class <b>D</b> addresses (in the range 224.0.0.0 to
137
 
                /// 239.255.255.255).  Multicast packets can pass across different networks through routers, so
138
 
                /// it is possible to use multicasts in an Internet scenario as long as your network provider 
139
 
                /// supports multicasting.
140
 
                /// </para>
141
 
                /// <para>
142
 
                /// Hosts that want to receive particular multicast messages must register their interest by joining
143
 
                /// the multicast group.  Multicast messages are not sent to networks where no host has joined
144
 
                /// the multicast group.  Class <b>D</b> IP addresses are used for multicast groups, to differentiate
145
 
                /// them from normal host addresses, allowing nodes to easily detect if a message is of interest.
146
 
                /// </para>
147
 
                /// <para>
148
 
                /// Static multicast addresses that are needed globally are assigned by IANA.  A few examples are listed in the table below:
149
 
                /// </para>
150
 
                /// <para>
151
 
                /// <list type="table">
152
 
                ///     <listheader>
153
 
                ///         <term>IP Address</term>
154
 
                ///         <description>Description</description>
155
 
                ///     </listheader>
156
 
                ///     <item>
157
 
                ///         <term>224.0.0.1</term>
158
 
                ///         <description>
159
 
                ///             <para>
160
 
                ///             Sends a message to all system on the subnet.
161
 
                ///             </para>
162
 
                ///         </description>
163
 
                ///     </item>
164
 
                ///     <item>
165
 
                ///         <term>224.0.0.2</term>
166
 
                ///         <description>
167
 
                ///             <para>
168
 
                ///             Sends a message to all routers on the subnet.
169
 
                ///             </para>
170
 
                ///         </description>
171
 
                ///     </item>
172
 
                ///     <item>
173
 
                ///         <term>224.0.0.12</term>
174
 
                ///         <description>
175
 
                ///             <para>
176
 
                ///             The DHCP server answers messages on the IP address 224.0.0.12, but only on a subnet.
177
 
                ///             </para>
178
 
                ///         </description>
179
 
                ///     </item>
180
 
                /// </list>
181
 
                /// </para>
182
 
                /// <para>
183
 
                /// A complete list of actually reserved multicast addresses and their owners in the ranges
184
 
                /// defined by RFC 3171 can be found at the <A href="http://www.iana.org/assignments/multicast-addresses">IANA web site</A>. 
185
 
                /// </para>
186
 
                /// <para>
187
 
                /// The address range 239.0.0.0 to 239.255.255.255 is reserved for administrative scope-relative 
188
 
                /// addresses.  These addresses can be reused with other local groups.  Routers are typically 
189
 
                /// configured with filters to prevent multicast traffic in this range from flowing outside
190
 
                /// of the local network.
191
 
                /// </para>
192
 
                /// </remarks>
193
 
                public IPAddress RemoteAddress
194
 
                {
195
 
                        get { return m_remoteAddress; }
196
 
                        set { m_remoteAddress = value; }
197
 
                }
198
 
 
199
 
                /// <summary>
200
 
                /// Gets or sets the TCP port number of the remote host or multicast group to which 
201
 
                /// the underlying <see cref="UdpClient" /> should sent the logging event.
202
 
                /// </summary>
203
 
                /// <value>
204
 
                /// An integer value in the range <see cref="IPEndPoint.MinPort" /> to <see cref="IPEndPoint.MaxPort" /> 
205
 
                /// indicating the TCP port number of the remote host or multicast group to which the logging event 
206
 
                /// will be sent.
207
 
                /// </value>
208
 
                /// <remarks>
209
 
                /// The underlying <see cref="UdpClient" /> will send messages to this TCP port number
210
 
                /// on the remote host or multicast group.
211
 
                /// </remarks>
212
 
                /// <exception cref="ArgumentOutOfRangeException">The value specified is less than <see cref="IPEndPoint.MinPort" /> or greater than <see cref="IPEndPoint.MaxPort" />.</exception>
213
 
                public int RemotePort
214
 
                {
215
 
                        get { return m_remotePort; }
216
 
                        set 
217
 
                        {
218
 
                                if (value < IPEndPoint.MinPort || value > IPEndPoint.MaxPort) 
219
 
                                {
220
 
                                        throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("value", (object)value,
221
 
                                                "The value specified is less than " + 
222
 
                                                IPEndPoint.MinPort.ToString(NumberFormatInfo.InvariantInfo) + 
223
 
                                                " or greater than " + 
224
 
                                                IPEndPoint.MaxPort.ToString(NumberFormatInfo.InvariantInfo) + ".");
225
 
                                } 
226
 
                                else 
227
 
                                {
228
 
                                        m_remotePort = value;
229
 
                                }
230
 
                        }
231
 
                }
232
 
 
233
 
                /// <summary>
234
 
                /// Gets or sets the TCP port number from which the underlying <see cref="UdpClient" /> will communicate.
235
 
                /// </summary>
236
 
                /// <value>
237
 
                /// An integer value in the range <see cref="IPEndPoint.MinPort" /> to <see cref="IPEndPoint.MaxPort" /> 
238
 
                /// indicating the TCP port number from which the underlying <see cref="UdpClient" /> will communicate.
239
 
                /// </value>
240
 
                /// <remarks>
241
 
                /// <para>
242
 
                /// The underlying <see cref="UdpClient" /> will bind to this port for sending messages.
243
 
                /// </para>
244
 
                /// <para>
245
 
                /// Setting the value to 0 (the default) will cause the udp client not to bind to
246
 
                /// a local port.
247
 
                /// </para>
248
 
                /// </remarks>
249
 
                /// <exception cref="ArgumentOutOfRangeException">The value specified is less than <see cref="IPEndPoint.MinPort" /> or greater than <see cref="IPEndPoint.MaxPort" />.</exception>
250
 
                public int LocalPort
251
 
                {
252
 
                        get { return m_localPort; }
253
 
                        set 
254
 
                        {
255
 
                                if (value != 0 && (value < IPEndPoint.MinPort || value > IPEndPoint.MaxPort))
256
 
                                {
257
 
                                        throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("value", (object)value,
258
 
                                                "The value specified is less than " + 
259
 
                                                IPEndPoint.MinPort.ToString(NumberFormatInfo.InvariantInfo) + 
260
 
                                                " or greater than " + 
261
 
                                                IPEndPoint.MaxPort.ToString(NumberFormatInfo.InvariantInfo) + ".");
262
 
                                } 
263
 
                                else 
264
 
                                {
265
 
                                        m_localPort = value;
266
 
                                }
267
 
                        }
268
 
                }
269
 
 
270
 
                /// <summary>
271
 
                /// Gets or sets <see cref="Encoding"/> used to write the packets.
272
 
                /// </summary>
273
 
                /// <value>
274
 
                /// The <see cref="Encoding"/> used to write the packets.
275
 
                /// </value>
276
 
                /// <remarks>
277
 
                /// <para>
278
 
                /// The <see cref="Encoding"/> used to write the packets.
279
 
                /// </para>
280
 
                /// </remarks>
281
 
                public Encoding Encoding
282
 
                {
283
 
                        get { return m_encoding; }
284
 
                        set { m_encoding = value; }
285
 
                }
286
 
 
287
 
                #endregion Public Instance Properties
288
 
 
289
 
                #region Protected Instance Properties
290
 
 
291
 
                /// <summary>
292
 
                /// Gets or sets the underlying <see cref="UdpClient" />.
293
 
                /// </summary>
294
 
                /// <value>
295
 
                /// The underlying <see cref="UdpClient" />.
296
 
                /// </value>
297
 
                /// <remarks>
298
 
                /// <see cref="UdpAppender" /> creates a <see cref="UdpClient" /> to send logging events 
299
 
                /// over a network.  Classes deriving from <see cref="UdpAppender" /> can use this
300
 
                /// property to get or set this <see cref="UdpClient" />.  Use the underlying <see cref="UdpClient" />
301
 
                /// returned from <see cref="Client" /> if you require access beyond that which 
302
 
                /// <see cref="UdpAppender" /> provides.
303
 
                /// </remarks>
304
 
                protected UdpClient Client
305
 
                {
306
 
                        get { return this.m_client; }
307
 
                        set { this.m_client = value; }
308
 
                }
309
 
 
310
 
                /// <summary>
311
 
                /// Gets or sets the cached remote endpoint to which the logging events should be sent.
312
 
                /// </summary>
313
 
                /// <value>
314
 
                /// The cached remote endpoint to which the logging events will be sent.
315
 
                /// </value>
316
 
                /// <remarks>
317
 
                /// The <see cref="ActivateOptions" /> method will initialize the remote endpoint 
318
 
                /// with the values of the <see cref="RemoteAddress" /> and <see cref="RemotePort"/>
319
 
                /// properties.
320
 
                /// </remarks>
321
 
                protected IPEndPoint RemoteEndPoint
322
 
                {
323
 
                        get { return this.m_remoteEndPoint; }
324
 
                        set { this.m_remoteEndPoint = value; }
325
 
                }
326
 
 
327
 
                #endregion Protected Instance Properties
328
 
 
329
 
                #region Implementation of IOptionHandler
330
 
 
331
 
                /// <summary>
332
 
                /// Initialize the appender based on the options set.
333
 
                /// </summary>
334
 
                /// <remarks>
335
 
                /// <para>
336
 
                /// This is part of the <see cref="IOptionHandler"/> delayed object
337
 
                /// activation scheme. The <see cref="ActivateOptions"/> method must 
338
 
                /// be called on this object after the configuration properties have
339
 
                /// been set. Until <see cref="ActivateOptions"/> is called this
340
 
                /// object is in an undefined state and must not be used. 
341
 
                /// </para>
342
 
                /// <para>
343
 
                /// If any of the configuration properties are modified then 
344
 
                /// <see cref="ActivateOptions"/> must be called again.
345
 
                /// </para>
346
 
                /// <para>
347
 
                /// The appender will be ignored if no <see cref="RemoteAddress" /> was specified or 
348
 
                /// an invalid remote or local TCP port number was specified.
349
 
                /// </para>
350
 
                /// </remarks>
351
 
                /// <exception cref="ArgumentNullException">The required property <see cref="RemoteAddress" /> was not specified.</exception>
352
 
                /// <exception cref="ArgumentOutOfRangeException">The TCP port number assigned to <see cref="LocalPort" /> or <see cref="RemotePort" /> is less than <see cref="IPEndPoint.MinPort" /> or greater than <see cref="IPEndPoint.MaxPort" />.</exception>
353
 
                public override void ActivateOptions()
354
 
                {
355
 
                        base.ActivateOptions();
356
 
 
357
 
                        if (this.RemoteAddress == null) 
358
 
                        {
359
 
                                throw new ArgumentNullException("The required property 'Address' was not specified.");
360
 
                        } 
361
 
                        else if (this.RemotePort < IPEndPoint.MinPort || this.RemotePort > IPEndPoint.MaxPort) 
362
 
                        {
363
 
                                throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("this.RemotePort", (object)this.RemotePort,
364
 
                                        "The RemotePort is less than " + 
365
 
                                        IPEndPoint.MinPort.ToString(NumberFormatInfo.InvariantInfo) + 
366
 
                                        " or greater than " + 
367
 
                                        IPEndPoint.MaxPort.ToString(NumberFormatInfo.InvariantInfo) + ".");
368
 
                        } 
369
 
                        else if (this.LocalPort != 0 && (this.LocalPort < IPEndPoint.MinPort || this.LocalPort > IPEndPoint.MaxPort))
370
 
                        {
371
 
                                throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("this.LocalPort", (object)this.LocalPort,
372
 
                                        "The LocalPort is less than " + 
373
 
                                        IPEndPoint.MinPort.ToString(NumberFormatInfo.InvariantInfo) + 
374
 
                                        " or greater than " + 
375
 
                                        IPEndPoint.MaxPort.ToString(NumberFormatInfo.InvariantInfo) + ".");
376
 
                        } 
377
 
                        else 
378
 
                        {
379
 
                                this.RemoteEndPoint = new IPEndPoint(this.RemoteAddress, this.RemotePort);
380
 
                                this.InitializeClientConnection();
381
 
                        }
382
 
                }
383
 
 
384
 
                #endregion
385
 
 
386
 
                #region Override implementation of AppenderSkeleton
387
 
 
388
 
                /// <summary>
389
 
                /// This method is called by the <see cref="AppenderSkeleton.DoAppend(LoggingEvent)"/> method.
390
 
                /// </summary>
391
 
                /// <param name="loggingEvent">The event to log.</param>
392
 
                /// <remarks>
393
 
                /// <para>
394
 
                /// Sends the event using an UDP datagram.
395
 
                /// </para>
396
 
                /// <para>
397
 
                /// Exceptions are passed to the <see cref="AppenderSkeleton.ErrorHandler"/>.
398
 
                /// </para>
399
 
                /// </remarks>
400
 
                protected override void Append(LoggingEvent loggingEvent) 
401
 
                {
402
 
                        try 
403
 
                        {
404
 
                                Byte [] buffer = m_encoding.GetBytes(RenderLoggingEvent(loggingEvent).ToCharArray());
405
 
                                this.Client.Send(buffer, buffer.Length, this.RemoteEndPoint);
406
 
                        } 
407
 
                        catch (Exception ex) 
408
 
                        {
409
 
                                ErrorHandler.Error(
410
 
                                        "Unable to send logging event to remote host " + 
411
 
                                        this.RemoteAddress.ToString() + 
412
 
                                        " on port " + 
413
 
                                        this.RemotePort + ".", 
414
 
                                        ex, 
415
 
                                        ErrorCode.WriteFailure);
416
 
                        }
417
 
                }
418
 
 
419
 
                /// <summary>
420
 
                /// This appender requires a <see cref="Layout"/> to be set.
421
 
                /// </summary>
422
 
                /// <value><c>true</c></value>
423
 
                /// <remarks>
424
 
                /// <para>
425
 
                /// This appender requires a <see cref="Layout"/> to be set.
426
 
                /// </para>
427
 
                /// </remarks>
428
 
                override protected bool RequiresLayout
429
 
                {
430
 
                        get { return true; }
431
 
                }
432
 
 
433
 
                /// <summary>
434
 
                /// Closes the UDP connection and releases all resources associated with 
435
 
                /// this <see cref="UdpAppender" /> instance.
436
 
                /// </summary>
437
 
                /// <remarks>
438
 
                /// <para>
439
 
                /// Disables the underlying <see cref="UdpClient" /> and releases all managed 
440
 
                /// and unmanaged resources associated with the <see cref="UdpAppender" />.
441
 
                /// </para>
442
 
                /// </remarks>
443
 
                override protected void OnClose() 
444
 
                {
445
 
                        base.OnClose();
446
 
 
447
 
                        if (this.Client != null) 
448
 
                        {
449
 
                                this.Client.Close();
450
 
                                this.Client = null;
451
 
                        }
452
 
                }
453
 
 
454
 
                #endregion Override implementation of AppenderSkeleton
455
 
 
456
 
                #region Protected Instance Methods
457
 
 
458
 
                /// <summary>
459
 
                /// Initializes the underlying  <see cref="UdpClient" /> connection.
460
 
                /// </summary>
461
 
                /// <remarks>
462
 
                /// <para>
463
 
                /// The underlying <see cref="UdpClient"/> is initialized and binds to the 
464
 
                /// port number from which you intend to communicate.
465
 
                /// </para>
466
 
                /// <para>
467
 
                /// Exceptions are passed to the <see cref="AppenderSkeleton.ErrorHandler"/>.
468
 
                /// </para>
469
 
                /// </remarks>
470
 
                protected virtual void InitializeClientConnection() 
471
 
                {
472
 
                        try 
473
 
                        {
474
 
                                if (this.LocalPort == 0)
475
 
                                {
476
 
                                        this.Client = new UdpClient();
477
 
                                }
478
 
                                else
479
 
                                {
480
 
                                        this.Client = new UdpClient(this.LocalPort);
481
 
                                }
482
 
                        } 
483
 
                        catch (Exception ex) 
484
 
                        {
485
 
                                ErrorHandler.Error(
486
 
                                        "Could not initialize the UdpClient connection on port " + 
487
 
                                        this.LocalPort.ToString(NumberFormatInfo.InvariantInfo) + ".", 
488
 
                                        ex, 
489
 
                                        ErrorCode.GenericFailure);
490
 
 
491
 
                                this.Client = null;
492
 
                        }
493
 
                }
494
 
 
495
 
                #endregion Protected Instance Methods
496
 
 
497
 
                #region Private Instance Fields
498
 
 
499
 
                /// <summary>
500
 
                /// The IP address of the remote host or multicast group to which 
501
 
                /// the logging event will be sent.
502
 
                /// </summary>
503
 
                private IPAddress m_remoteAddress;
504
 
                
505
 
                /// <summary>
506
 
                /// The TCP port number of the remote host or multicast group to 
507
 
                /// which the logging event will be sent.
508
 
                /// </summary>
509
 
                private int m_remotePort;
510
 
 
511
 
                /// <summary>
512
 
                /// The cached remote endpoint to which the logging events will be sent.
513
 
                /// </summary>
514
 
                private IPEndPoint m_remoteEndPoint;
515
 
 
516
 
                /// <summary>
517
 
                /// The TCP port number from which the <see cref="UdpClient" /> will communicate.
518
 
                /// </summary>
519
 
                private int m_localPort;
520
 
 
521
 
                /// <summary>
522
 
                /// The <see cref="UdpClient" /> instance that will be used for sending the 
523
 
                /// logging events.
524
 
                /// </summary>
525
 
                private UdpClient m_client;
526
 
 
527
 
                /// <summary>
528
 
                /// The encoding to use for the packet.
529
 
                /// </summary>
530
 
                private Encoding m_encoding = Encoding.Default;
531
 
 
532
 
                #endregion Private Instance Fields
533
 
        }
534
 
}