예제 #1
0
        /// <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();
            }
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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();
        }
예제 #4
0
        /// <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);
        }