/// <summary> /// Flushes all buffers that contain data by calling each buffer handler's StoreMessages method. /// </summary> public void Flush() { // Get a fast, one-way, read-only enumer of the buffers' keys var enumer = _buffers.Keys.GetEnumerator(); List <string[]> copiedList = null; // Ensure that a buffer is defined if (enumer.Current == null) { enumer.MoveNext(); } while (enumer.Current != null) { var currentVal = _buffers[enumer.Current]; // Lock the buffer while a copy is made so that new entries being added do not block or fail the copy. lock (currentVal) { try { if (currentVal.Count > 0) { copiedList = DeepCopy(currentVal); // Ensure that the copied object contains the same number of messages. if (copiedList.Count != currentVal.Count) { EventLogger.LogEvent("An error occured while storing messages for " + enumer.Current, System.Diagnostics.EventLogEntryType.Error); } // Clear the buffer. currentVal.Clear(); } } catch (Exception ex) { EventLogger.LogEvent("Could not store messages from " + enumer.Current + " because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); } finally { Monitor.Pulse(currentVal); } } if (copiedList != null && copiedList.Count > 0) { try { // Get a refence to the storer interface of the handler var storer = _handlers[enumer.Current].GetStorer(); if (storer != null) { //Process the list of messages if (!storer.StoreMessages(copiedList)) { EventLogger.LogEvent("An error occured while storing messages for " + enumer.Current, System.Diagnostics.EventLogEntryType.Warning); } else { copiedList.Clear(); } } } catch (Exception ex) { EventLogger.LogEvent("Could not store message from " + enumer.Current + " because: " + ex.Message, System.Diagnostics.EventLogEntryType.Warning); } } enumer.MoveNext(); } }
/// <summary> /// Creates a socket that waits for traffic and sets up the handler modules /// </summary> /// <returns>Returns true if the listener starts successfully. Otherwise, false.</returns> public bool Start() { HandlerSection handlers; // Get the handlers collection Trace.WriteLine("Loading handlers"); try { handlers = (HandlerSection)System.Configuration.ConfigurationManager.GetSection("handlerSection"); } catch (Exception ex) { EventLogger.LogEvent("Could not load configuration because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); return(false); } // Ensure that a socket needs to be initialized. if (_socket != null) { return(true); } // Ensure that a socket needs to be initialized and bound. if (_socket != null && _socket.IsBound) { return(true); } try { _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); } catch (Exception ex) { EventLogger.LogEvent("Could not create socket because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); return(false); } Trace.WriteLine("Binding socket"); // Bind the socket to the specificed IP and port try { _socket.Bind(new IPEndPoint(_listenAddress, _listenPort)); } catch (Exception ex) { _socket.Close(); _socket = null; EventLogger.LogEvent("Could not bind socket because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); return(false); } if (_socket == null) { return(false); } // Create a new LogBuffer that will be used to store messages until they are discarded or flushed to a persistent store. _buffer = new LogBuffer(_logBufferFlushFrequency); if (handlers != null) { Trace.WriteLine("Initialising handlers"); // Load each module (handler) from the configuration file foreach (HandlerConfiguration handler in handlers.Handlers) { IDictionary <string, string> properties = new Dictionary <string, string>(); handler.HandlerProperties.AllKeys.All(key => { properties[key] = handler.HandlerProperties[key].Value; return(true); }); var msgHandler = new MessageHandler(handler.AssemblyName, handler.ParserClassName, handler.StorageClassName, handler.ConnectionString, properties); // If the handler has a storage class then setup the buffer to temporarily store the messages if (handler.StorageClassName != null) { Trace.WriteLine("Intialising buffer"); _buffer.InitHandler(msgHandler); } // If the handler is configured for specific IP addresses, setup the IP handler lookup list if (!string.IsNullOrEmpty(handler.FilterIPAddresses)) { var filters = handler.FilterIPAddresses.Split(',', ';'); foreach (var filter in filters) { _ipFilters.Add(filter, msgHandler); // If the handler also has IP forwards set, add them to the IP Forwards lookup list if (!string.IsNullOrEmpty(handler.IPForwards)) { _ipForwards.Add(filter, handler.IPForwards.Split(',', ';')); } } } } } // If any handler has an IP forward setup, create a send socket that will be used forward messages if (_ipForwards.Count > 0) { try { _sendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); _sendSocket.Bind(new IPEndPoint(IPAddress.Any, 0)); } catch (Exception ex) { } } Trace.WriteLine("Registering receive event"); try { // Start the listen operation on the socket RegisterReceiveOperation(); } catch (Exception ex) { EventLogger.LogEvent("Could not register socket on data received event because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); return(false); } return(true); }
/// <summary> /// Processes a message received event. /// </summary> /// <param name="result">The result of a receive event.</param> private void ReceiveCallback(IAsyncResult result) { Trace.WriteLine("Receive callback"); // get a reference to the socket on which the message was received Socket sock = (Socket)result.AsyncState; EndPoint ep = null; IPEndPoint remoteEp = null; // variable to store received data length int inlen; _remoteEndpoint = new IPEndPoint(IPAddress.Any, 0); // Gather information about the message and the sender try { ep = _remoteEndpoint; inlen = sock.EndReceiveFrom(result, ref ep); remoteEp = (IPEndPoint)ep; } catch (Exception ex) { // only post messages if class socket reference is not null // in all other cases, the socket has been terminated if (_socket != null) { EventLogger.LogEvent("Receive operation failed with message: " + ex.Message, System.Diagnostics.EventLogEntryType.Warning); } inlen = -1; } // if socket has been closed, ignore received data and return if (_socket == null) { return; } // check that received data is long enough if (inlen <= 0) { // request next packet RegisterReceiveOperation(); return; } // If an IP forward is defined for the source of this message, forward the message to the specified IP's if (_ipForwards.ContainsKey(remoteEp.Address.ToString())) { if (_socket != null) { foreach (string ipAddress in _ipForwards[remoteEp.Address.ToString()]) { var sendBuffer = new byte[_receiveBuffer.Length]; _receiveBuffer.CopyTo(sendBuffer, 0); _sendSocket.BeginSendTo(sendBuffer, 0, inlen, SocketFlags.None, new IPEndPoint(IPAddress.Parse(ipAddress), 514), new AsyncCallback(SendCallback), _sendSocket); } } } string packet = null; // Get the human readable text of the message to process try { packet = System.Text.Encoding.ASCII.GetString(_receiveBuffer, 0, inlen); } catch (Exception ex) { EventLogger.LogEvent("Could not parse packet to string because: " + ex.Message, System.Diagnostics.EventLogEntryType.Warning); } // Run the regular expression against the message text to extract the groups var m = _msgRegex.Match(packet); //If a match is not found the message is not valid if (m != null && !string.IsNullOrEmpty(packet)) { //parse PRI section into a priority value int pri; var priority = int.TryParse(m.Groups["PRI"].Value, out pri) ? pri : 0; //parse the HEADER section - contains TIMESTAMP and HOSTNAME string hostname = null; DateTime?timestamp = null; // Get the timestamp and hostname from the header of the message if (!string.IsNullOrEmpty(m.Groups["HDR"].Value)) { if (!string.IsNullOrEmpty(m.Groups["TIMESTAMP"].Value)) { try { timestamp = new DateTime( DateTime.Now.Year, MonthNumber(m.Groups["MMM"].Value), int.Parse(m.Groups["DD"].Value), int.Parse(m.Groups["HH"].Value), int.Parse(m.Groups["MM"].Value), int.Parse(m.Groups["SS"].Value) ); } catch (ArgumentException) { //Ignore bad timestamp args. } } if (!string.IsNullOrEmpty(m.Groups["HOSTNAME"].Value)) { hostname = m.Groups["HOSTNAME"].Value; } } if (!timestamp.HasValue) { //add timestamp as per RFC3164 timestamp = DateTime.Now; } if (string.IsNullOrEmpty(hostname)) { hostname = ep.ToString(); } // Get the message text part of the message if it was found if ((m.Groups["MSG"].Value) != null) { var message = m.Groups["MSG"].Value; try { var sm = new SyslogMessage(priority, timestamp.Value, hostname, message); // Ensure that a handler is defined for the MessageReceived event if (MessageReceived != null) { Trace.WriteLine("Calling MessageReceived event"); MessageReceived(new MessageReceivedEventArgs(sm)); } //If the message is from an IP not listed in any filter do not process it if (!_ipFilters.ContainsKey(remoteEp.Address.ToString())) { Trace.WriteLine("Remote IP not listed in filter"); RegisterReceiveOperation(); return; } string[] parsedMsg = null; if (_ipFilters[remoteEp.Address.ToString()].ParserClassName != null) { try { // Parse the message using the parser defined for IP from where the message came parsedMsg = _ipFilters[remoteEp.Address.ToString()].GetParser().Parse(sm); } catch (Exception ex) { EventLogger.LogEvent("Could not get parser or parse message for ip " + remoteEp.Address.ToString() + " because: " + ex.Message, System.Diagnostics.EventLogEntryType.Warning); } } // Add the message to the LogBuffer if a storage Class is defined and message was parsed successfully. if (parsedMsg != null && _buffer != null && _ipFilters[remoteEp.Address.ToString()].StorerClassName != null) { Trace.WriteLine("Adding message to buffer"); _buffer.AddEntry(_ipFilters[remoteEp.Address.ToString()].AssemblyName, parsedMsg); } } catch (Exception ex) { EventLogger.LogEvent("Could not create new SyslogMessage because: " + ex.Message, System.Diagnostics.EventLogEntryType.Warning); } } } // Return the socket to the listen state RegisterReceiveOperation(); }
/// <summary> /// Creates a socket that waits for traffic and sets up the handler modules /// </summary> /// <returns>Returns true if the listener starts successfully. Otherwise, false.</returns> public bool Start() { HandlerSection handlers; // Get the handlers collection try { handlers = (HandlerSection)System.Configuration.ConfigurationManager.GetSection("handlerSection"); } catch (Exception ex) { EventLogger.LogEvent("Could not load configuration because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); return(false); } // Ensure that a socket needs to be initialized. if (this.socket != null) { return(true); } // Ensure that a socket needs to be initialized and bound. if (this.socket != null && this.socket.IsBound) { return(true); } try { this.socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); } catch (Exception ex) { EventLogger.LogEvent("Could not create socket because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); return(false); } // Bind the socket to the specificed IP and port try { this.socket.Bind(new IPEndPoint(this.listenAddress, SYSLOG_PORT)); } catch (Exception ex) { this.socket.Close(); this.socket = null; EventLogger.LogEvent("Could not bind socket because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); return(false); } if (this.socket == null) { return(false); } // Create a new LogBuffer that will be used to store messages until they are discarded or flushed to a persistent store. buffer = new LogBuffer(this.logBufferFlushFrequency); if (handlers != null) { // Load each module (handler) from the configuration file foreach (HandlerConfiguration handler in handlers.Handlers) { MessageHandler msgHandler = new MessageHandler(handler.AssemblyName, handler.ParserClassName, handler.StorageClassName, handler.ConnectionString); // If the handler has a storage class then setup the buffer to temporarily store the messages if (handler.StorageClassName != null) { buffer.InitializeBuffer(msgHandler); } // If the handler is configured for specific IP addresses, setup the IP handler lookup list if (handler.FilterIPAddresses != null) { string[] filters = handler.FilterIPAddresses.Split(',', ';'); for (int i = 0; i < filters.Length; i++) { ipFilters.Add(filters[i], msgHandler); // If the handler also has IP forwards set, add them to the IP Forwards lookup list if (handler.IPForwards != null && handler.IPForwards.Length > 0) { ipForwards.Add(filters[i], handler.IPForwards.Split(',', ';')); } } } } } // If any handler has an IP forward setup, create a send socket that will be used forward messages if (ipForwards.Count > 0) { try { sendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); sendSocket.Bind(new IPEndPoint(IPAddress.Any, 0)); } catch (Exception ex) { } } try { // Start the listen operation on the socket RegisterReceiveOperation(); } catch (Exception ex) { EventLogger.LogEvent("Could not register socket on data received event because: " + ex.Message, System.Diagnostics.EventLogEntryType.Error); return(false); } return(true); }