From f1b811011c896703519868a03fb78db5aa3c79a4 Mon Sep 17 00:00:00 2001 From: thenotandy Date: Mon, 8 Aug 2016 12:52:55 -0400 Subject: [PATCH] Initial Commit From http://www.fantail.net.nz/downloads/FantailSyslogServerSrc.zip --- .../Fantail.SyslogServer.csproj | 71 ++++ Fantail.SyslogServer/LICENSE.TXT | 34 ++ Fantail.SyslogServer/MemoryBuffer.cs | 97 +++++ Fantail.SyslogServer/Program.cs | 49 +++ .../ProjectInstaller.Designer.cs | 91 +++++ Fantail.SyslogServer/ProjectInstaller.cs | 17 + Fantail.SyslogServer/ProjectInstaller.resx | 129 +++++++ .../Properties/AssemblyInfo.cs | 67 ++++ Fantail.SyslogServer/SqlUpdater.cs | 219 +++++++++++ Fantail.SyslogServer/SyslogListener.cs | 357 ++++++++++++++++++ .../SyslogService.Designer.cs | 67 ++++ Fantail.SyslogServer/SyslogService.cs | 102 +++++ .../Fantail.SyslogServer.csproj.FileList.txt | 14 + Fantail.SyslogServer/readme.txt | 152 ++++++++ LICENSE.TXT | 34 ++ SyslogServer.sln | 20 + SyslogServer.suo | Bin 0 -> 30720 bytes readme.txt | 152 ++++++++ 18 files changed, 1672 insertions(+) create mode 100644 Fantail.SyslogServer/Fantail.SyslogServer.csproj create mode 100644 Fantail.SyslogServer/LICENSE.TXT create mode 100644 Fantail.SyslogServer/MemoryBuffer.cs create mode 100644 Fantail.SyslogServer/Program.cs create mode 100644 Fantail.SyslogServer/ProjectInstaller.Designer.cs create mode 100644 Fantail.SyslogServer/ProjectInstaller.cs create mode 100644 Fantail.SyslogServer/ProjectInstaller.resx create mode 100644 Fantail.SyslogServer/Properties/AssemblyInfo.cs create mode 100644 Fantail.SyslogServer/SqlUpdater.cs create mode 100644 Fantail.SyslogServer/SyslogListener.cs create mode 100644 Fantail.SyslogServer/SyslogService.Designer.cs create mode 100644 Fantail.SyslogServer/SyslogService.cs create mode 100644 Fantail.SyslogServer/obj/Fantail.SyslogServer.csproj.FileList.txt create mode 100644 Fantail.SyslogServer/readme.txt create mode 100644 LICENSE.TXT create mode 100644 SyslogServer.sln create mode 100644 SyslogServer.suo create mode 100644 readme.txt diff --git a/Fantail.SyslogServer/Fantail.SyslogServer.csproj b/Fantail.SyslogServer/Fantail.SyslogServer.csproj new file mode 100644 index 0000000..e15bee7 --- /dev/null +++ b/Fantail.SyslogServer/Fantail.SyslogServer.csproj @@ -0,0 +1,71 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {2276C92F-8444-47B4-B3C9-AF507C41BB98} + WinExe + Properties + Fantail.SyslogServer + Fantail.SyslogServer + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + Component + + + ProjectInstaller.cs + + + + + Component + + + SyslogService.cs + + + + + + + Designer + ProjectInstaller.cs + + + + + \ No newline at end of file diff --git a/Fantail.SyslogServer/LICENSE.TXT b/Fantail.SyslogServer/LICENSE.TXT new file mode 100644 index 0000000..c40d87d --- /dev/null +++ b/Fantail.SyslogServer/LICENSE.TXT @@ -0,0 +1,34 @@ + + Fantail.SyslogServer + ==================== + + Fantail Technology Ltd ( www.fantail.net.nz ) + + Designed by Chris Guthrey & David Husselmann + Developed by David Husselmann for Fantail Technology Ltd + + chris@fantail.net.nz + david@tamix.com + + Copyright (c) 2007, Fantail Technology Ltd + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + diff --git a/Fantail.SyslogServer/MemoryBuffer.cs b/Fantail.SyslogServer/MemoryBuffer.cs new file mode 100644 index 0000000..3b8142d --- /dev/null +++ b/Fantail.SyslogServer/MemoryBuffer.cs @@ -0,0 +1,97 @@ +/// +/// Fantail.SyslogServer +/// ==================== +/// +/// Fantail Technology Ltd ( www.fantail.net.nz ) +/// +/// Designed by Chris Guthrey & David Husselmann +/// Developed by David Husselmann for Fantail Technology Ltd +/// +/// chris@fantail.net.nz +/// david@tamix.com +/// +/// Copyright (c) 2007, Fantail Technology Ltd +/// +/// All rights reserved. +/// +/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +/// +/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +/// * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +/// +/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +/// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +/// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE +/// +using System; +using System.Collections.Generic; +using System.Text; +using Fantail.Libraries.Syslog; +using System.Timers; +using System.Threading; + +namespace Fantail.Libraries.Syslog { + /// + /// This class takes care of buffering incoming syslog messages in memory + /// and submitting them to the SqlUpdater in batches, rather than keeping the database + /// occupied with drip-fed messages. + /// + public class MemoryBuffer { + private List buffer = new List(); + private TimeSpan commitInterval; + private System.Timers.Timer timer = new System.Timers.Timer(); + private SqlUpdater sqlUpdater; + private Mutex bufferLock = new Mutex(false); + + /// + /// Creates a new instance of the MemoryBuffer class. + /// + /// Specifies the interval at which message batches should be committed to the database. + /// The pre-initialised SqlUpdater to which messages should be submitted. + public MemoryBuffer(TimeSpan commitInterval, SqlUpdater sqlUpdater) { + this.commitInterval = commitInterval; + this.timer.Interval = commitInterval.TotalMilliseconds; + this.sqlUpdater = sqlUpdater; + this.timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); + this.timer.Enabled = true; + } + + void timer_Elapsed(object sender, ElapsedEventArgs e) { + Flush(); + } + + /// + /// Posts a new message to the buffer, for committing to the database when the internal timer elapses. + /// + /// The syslog message to be submitted. + public void PushMessage(SyslogMessage sm) { + bufferLock.WaitOne(); + buffer.Add(sm); + bufferLock.ReleaseMutex(); + } + + /// + /// Flushes the buffer. This method can be called by the user to ensure that final in-memory entries are + /// written to the database. + /// + public void Flush() { + bufferLock.WaitOne(); + try { + if (sqlUpdater.SaveMessage(buffer)) { + buffer.Clear(); + } + } finally { + bufferLock.ReleaseMutex(); + } + } + } +} diff --git a/Fantail.SyslogServer/Program.cs b/Fantail.SyslogServer/Program.cs new file mode 100644 index 0000000..9657eab --- /dev/null +++ b/Fantail.SyslogServer/Program.cs @@ -0,0 +1,49 @@ +/// +/// Fantail.SyslogServer +/// ==================== +/// +/// Fantail Technology Ltd ( www.fantail.net.nz ) +/// +/// Designed by Chris Guthrey & David Husselmann +/// Developed by David Husselmann for Fantail Technology Ltd +/// +/// chris@fantail.net.nz +/// david@tamix.com +/// +/// Copyright (c) 2007, Fantail Technology Ltd +/// +/// All rights reserved. +/// +/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +/// +/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +/// * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +/// +/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +/// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +/// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE +/// +using System.Collections.Generic; +using System.ServiceProcess; +using System.Text; + +namespace Fantail.SyslogServer { + static class Program { + static void Main() { + ServiceBase[] ServicesToRun; + + ServicesToRun = new ServiceBase[] { new SyslogService() }; + + ServiceBase.Run(ServicesToRun); + } + } +} \ No newline at end of file diff --git a/Fantail.SyslogServer/ProjectInstaller.Designer.cs b/Fantail.SyslogServer/ProjectInstaller.Designer.cs new file mode 100644 index 0000000..4b800b0 --- /dev/null +++ b/Fantail.SyslogServer/ProjectInstaller.Designer.cs @@ -0,0 +1,91 @@ +/// +/// Fantail.SyslogServer +/// ==================== +/// +/// Fantail Technology Ltd ( www.fantail.net.nz ) +/// +/// Designed by Chris Guthrey & David Husselmann +/// Developed by David Husselmann for Fantail Technology Ltd +/// +/// chris@fantail.net.nz +/// david@tamix.com +/// +/// Copyright (c) 2007, Fantail Technology Ltd +/// +/// All rights reserved. +/// +/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +/// +/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +/// * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +/// +/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +/// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +/// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE +/// +namespace Fantail.SyslogServer +{ + partial class ProjectInstaller { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() { + this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller(); + this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller(); + // + // serviceProcessInstaller1 + // + this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalService; + this.serviceProcessInstaller1.Password = null; + this.serviceProcessInstaller1.Username = null; + // + // serviceInstaller1 + // + this.serviceInstaller1.Description = "SYSLOG server which saves log entries to an SQL database."; + this.serviceInstaller1.DisplayName = "Fantail Syslog Server"; + this.serviceInstaller1.ServiceName = "Fantail.SyslogServer"; + this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic; + this.serviceInstaller1.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.serviceInstaller1_AfterInstall); + // + // ProjectInstaller + // + this.Installers.AddRange(new System.Configuration.Install.Installer[] { + this.serviceProcessInstaller1, + this.serviceInstaller1}); + + } + + #endregion + + private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1; + private System.ServiceProcess.ServiceInstaller serviceInstaller1; + } +} \ No newline at end of file diff --git a/Fantail.SyslogServer/ProjectInstaller.cs b/Fantail.SyslogServer/ProjectInstaller.cs new file mode 100644 index 0000000..5c4194f --- /dev/null +++ b/Fantail.SyslogServer/ProjectInstaller.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Configuration.Install; + +namespace Fantail.SyslogServer { + [RunInstaller(true)] + public partial class ProjectInstaller : Installer { + public ProjectInstaller() { + InitializeComponent(); + } + + private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e) { + + } + } +} \ No newline at end of file diff --git a/Fantail.SyslogServer/ProjectInstaller.resx b/Fantail.SyslogServer/ProjectInstaller.resx new file mode 100644 index 0000000..5860189 --- /dev/null +++ b/Fantail.SyslogServer/ProjectInstaller.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 54 + + + 187, 17 + + + False + + \ No newline at end of file diff --git a/Fantail.SyslogServer/Properties/AssemblyInfo.cs b/Fantail.SyslogServer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..2078b9e --- /dev/null +++ b/Fantail.SyslogServer/Properties/AssemblyInfo.cs @@ -0,0 +1,67 @@ +/// +/// Fantail.SyslogServer +/// ==================== +/// +/// Fantail Technology Ltd ( www.fantail.net.nz ) +/// +/// Designed by Chris Guthrey & David Husselmann +/// Developed by David Husselmann for Fantail Technology Ltd +/// +/// chris@fantail.net.nz +/// david@tamix.com +/// +/// Copyright (c) 2007, Fantail Technology Ltd +/// +/// All rights reserved. +/// +/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +/// +/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +/// * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +/// +/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +/// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +/// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE +/// +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Fantail.SyslogServer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Fantail Technology Ltd")] +[assembly: AssemblyProduct("Fantail.SyslogServer")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("af346163-428b-4300-8572-0977d93cf5d2")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Fantail.SyslogServer/SqlUpdater.cs b/Fantail.SyslogServer/SqlUpdater.cs new file mode 100644 index 0000000..fd84b65 --- /dev/null +++ b/Fantail.SyslogServer/SqlUpdater.cs @@ -0,0 +1,219 @@ +/// +/// Fantail.SyslogServer +/// ==================== +/// +/// Fantail Technology Ltd ( www.fantail.net.nz ) +/// +/// Designed by Chris Guthrey & David Husselmann +/// Developed by David Husselmann for Fantail Technology Ltd +/// +/// chris@fantail.net.nz +/// david@tamix.com +/// +/// Copyright (c) 2007, Fantail Technology Ltd +/// +/// All rights reserved. +/// +/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +/// +/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +/// * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +/// +/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +/// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +/// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE +/// +using System; +using System.Collections.Generic; +using System.Text; +using System.Data.SqlClient; +using Fantail.Libraries.Syslog; +using System.Threading; + +namespace Fantail.Libraries.Syslog { + /// + /// Takes care of inserting SyslogMessage records into a database. + /// + public class SqlUpdater : IDisposable { + private const string CHECK_SCHEMA_SQL = @" +declare @err varchar(2000) + +if not exists(select 1 from sysobjects where name=@TableName and xtype='U') begin + set @err = 'A table by the name '+isnull(@TableName,'NULL')+' does not exist in catalog '+DB_NAME()+'' + raiserror(@err,16,1) + return +end + +if exists( + select 1 + from ( + select 'Id' col, 'int' typ + union select 'Facility', 'int' + union select 'Severity', 'int' + union select 'Timestamp', 'datetime' + union select 'Hostname', 'varchar' + union select 'Message', 'varchar' + ) cols + left join information_schema.columns ic on cols.col=ic.column_name and cols.typ=ic.data_type and ic.table_name=@TableName + where ic.column_name is null +) begin + set @err = 'The table schema does not conform to the recommended structure. +The following SQL will create it for you: + +CREATE TABLE '+quotename(@TableName)+' ( + Id int identity(1,1), Facility int, Severity int, Timestamp datetime, + Hostname varchar(255), Message varchar(1024) +) +' + raiserror(@err,16,2) +end +"; + + private SqlConnection conn; + private string tableName; + + public SqlUpdater(string connectionString, string tableName) { + this.tableName = tableName; + conn = new SqlConnection(connectionString); + + //try opening the connection a couple times, if we're in a boot process + int tries = 10; + do { + conn.Open(); + if (tries != 10) Thread.Sleep(10000); + } while (tries-- > 0 && conn.State != System.Data.ConnectionState.Open); + + using (SqlCommand cmd = new SqlCommand(CHECK_SCHEMA_SQL, conn)) { + try { + cmd.Parameters.AddWithValue("@TableName", tableName); + cmd.ExecuteNonQuery(); + } catch (Exception ex) { + throw new Exception("Error checking the schema for the message table.", ex); + } + } + } + + /// + /// Submits the given syslog message to the database table. + /// + /// The syslog message to save. + /// True if the operation was successful. + public bool SaveMessage(SyslogMessage sm) { + List l = new List(); + l.Add(sm); + return SaveMessage(l); + } + + /// + /// Submits the given syslog messages to the database table in a single transaction. + /// + /// The syslog messages to save. + /// True if the operation was successful. + public bool SaveMessage(List syslogMessages) { + //DFH Note that this method gets called a lot, so be careful about + //disposing of stuff properly. + + if (syslogMessages.Count == 0) return true; + + StringBuilder sb = new StringBuilder(); + try { + //build the sql string + //Yep, it defies belief that using this rather than parameters is actually faster. + foreach (SyslogMessage sm in syslogMessages) { + sb.AppendFormat("INSERT INTO [" + tableName + "] (Facility, Severity, Timestamp, Hostname, Message) VALUES ({0},{1},'{2}','{3}','{4}')\n", + sm.Facility, sm.Severity, sm.Timestamp.ToString("yyyy-MM-dd hh:mm:ss.fff"), + sm.Hostname.Replace("'", "''"), + sm.Message.Replace("'", "''") + ); + } + + //check the connection + if (!PrepareForCommand()) return false; + + //submit the sql + using (SqlCommand cmd = new SqlCommand(sb.ToString(), conn)) { + try { + cmd.ExecuteNonQuery(); + } catch (Exception ex) { + DoExceptionThrown(ex); + return false; + } + } + + } finally { + sb = null; + } + + //if we get here, everything worked. + return true; + } + + private bool PrepareForCommand() { + if (conn.State != System.Data.ConnectionState.Open) { + //broken connection? try resetting it + try { + conn.Close(); + } catch (Exception) { + } + + try { + conn.Open(); + } catch (Exception ex) { + //error trying to open the connection; we better terminate. + DoExceptionThrown(new Exception("Error trying to reopen a failed SQL connection.",ex)); + return false; + } + } + return true; + } + + private void DoExceptionThrown(Exception e) { + if (ExceptionThrown != null) { + ExceptionThrown(new ExceptionThrownEventArgs(e)); + } else { + throw e; + } + } + + /// + /// This event gets invoked if an exception is thrown while talking to the database. + /// + public event ExceptionThrownEventHandler ExceptionThrown; + + /// + /// Called on disposing of this class. This will close the SqlConnection if it is still open. + /// + public void Dispose() { + if (conn.State != System.Data.ConnectionState.Closed) { + try { + conn.Close(); + } catch (Exception) { + } + } + } + } + + public delegate void ExceptionThrownEventHandler(ExceptionThrownEventArgs e); + /// + /// Encapsulates the exception thrown by internal code. + /// + public class ExceptionThrownEventArgs : EventArgs { + private Exception exception; + + public Exception Exception { + get { return exception; } + } + public ExceptionThrownEventArgs(Exception exception) { + this.exception = exception; + } + } +} diff --git a/Fantail.SyslogServer/SyslogListener.cs b/Fantail.SyslogServer/SyslogListener.cs new file mode 100644 index 0000000..1e5b7cf --- /dev/null +++ b/Fantail.SyslogServer/SyslogListener.cs @@ -0,0 +1,357 @@ +/// +/// Fantail.SyslogServer +/// ==================== +/// +/// Fantail Technology Ltd ( www.fantail.net.nz ) +/// +/// Designed by Chris Guthrey & David Husselmann +/// Developed by David Husselmann for Fantail Technology Ltd +/// +/// chris@fantail.net.nz +/// david@tamix.com +/// +/// Copyright (c) 2007, Fantail Technology Ltd +/// +/// All rights reserved. +/// +/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +/// +/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +/// * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +/// +/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +/// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +/// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE +/// +using System; +using System.Collections.Generic; +using System.Text; +using System.Net; +using System.Net.Sockets; +using System.Text.RegularExpressions; + +/* + * Syslog Listener library + * by David Husselmann + * for Fantail Technology Ltd + * + * Implements an RFC3164 compliant syslog listener which parses syslog messages + * sent to any interface the class is bound to. To use, instantiate the class: + * + * SyslogListener sl = new SyslogListener(IPAddress.Any); + * + * Attach a suitable event handler using the MessageReceived event: + * + * sl.MessageReceived += new MessageReceivedEventHandler(delegate(object sender, MessageReceivedEventArgs e) { + * Console.WriteLine("Got a message: ------------\n" + e.SyslogMessage.ToString()); + * }); + * + * And finally call the Start() and Stop() methods to control the class: + * + * sl.Start(); + * Console.ReadLine(); + * sl.Stop(); + * + */ + +/* CHANGELOG + * 20070813 DFH Initial version. + */ + +namespace Fantail.Libraries.Syslog { + + /// + /// Encapsulates a single syslog message, as received from a remote host. + /// + public struct SyslogMessage { + /// + /// Creates a new instance of the SyslogMessage class. + /// + /// Specifies the encoded PRI field, containing the facility and severity values. + /// Specifies the timestamp, if present in the packet. + /// Specifies the hostname, if present in the packet. The hostname can only be present if the timestamp is also present (RFC3164). + /// Specifies the textual content of the message. + public SyslogMessage(int? priority, DateTime timestamp, string hostname, string message) { + if (priority.HasValue) { + this.facility = (int)Math.Floor((double)priority.Value / 8); + this.severity = priority % 8; + } else { + this.facility = null; + this.severity = null; + } + this.timestamp = timestamp; + this.hostname = hostname; + this.message = message; + } + + private int? facility; + /// + /// Returns an integer specifying the facility. The following are commonly used: + /// 0 kernel messages + /// 1 user-level messages + /// 2 mail system + /// 3 system daemons + /// 4 security/authorization messages (note 1) + /// 5 messages generated internally by syslogd + /// 6 line printer subsystem + /// 7 network news subsystem + /// 8 UUCP subsystem + /// 9 clock daemon (note 2) + /// 10 security/authorization messages (note 1) + /// 11 FTP daemon + /// 12 NTP subsystem + /// 13 log audit (note 1) + /// 14 log alert (note 1) + /// 15 clock daemon (note 2) + /// 16 local use 0 (local0) + /// 17 local use 1 (local1) + /// 18 local use 2 (local2) + /// 19 local use 3 (local3) + /// 20 local use 4 (local4) + /// 21 local use 5 (local5) + /// 22 local use 6 (local6) + /// 23 local use 7 (local7) + /// + public int? Facility { + get { return facility; } + } + + private int? severity; + /// + /// Returns an integer number specifying the severity. The following values are commonly used: + /// 0 Emergency: system is unusable + /// 1 Alert: action must be taken immediately + /// 2 Critical: critical conditions + /// 3 Error: error conditions + /// 4 Warning: warning conditions + /// 5 Notice: normal but significant condition + /// 6 Informational: informational messages + /// 7 Debug: debug-level messages + /// + public int? Severity { + get { return severity; } + } + + private DateTime timestamp; + /// + /// Returns a DateTime specifying the moment at which the event is known to have happened. As per RFC3164, + /// if the host does not send this value, it may be added by a relay. + /// + public DateTime Timestamp { + get { return timestamp; } + } + + private string hostname; + /// + /// Returns the DNS hostname where the message originated, or the IP address if the hostname is unknown. + /// + public string Hostname { + get { return hostname; } + set { hostname = value; } + } + + private string message; + /// + /// Returns a string indicating the textual content of the message. + /// + public string Message { + get { return message; } + set { message = value; } + } + + /// + /// Returns a textual representation of the syslog message, for debugging purposes. + /// + /// + public override string ToString() { + return "Facility: " + this.facility + "\nSeverity: " + this.severity + + "\nTimestamp: "+this.timestamp+"\nHostname: "+this.hostname+"\nMessage: "+this.message; + } + } + + public delegate void MessageReceivedEventHandler(MessageReceivedEventArgs e); + + public class MessageReceivedEventArgs : EventArgs { + private SyslogMessage syslogMessage; + /// + /// Returns the syslog message as received from the remote host. + /// + public SyslogMessage SyslogMessage { + get { return syslogMessage; } + } + + /// + /// Creates a new instance of the MessageReceivedEventArgs class. + /// + public MessageReceivedEventArgs(SyslogMessage sm) : base() { + this.syslogMessage = sm; + } + } + + /// + /// Implements a syslog message listener which is RFC3164 compliant. + /// + public class SyslogListener { + private IPAddress listenAddress; + private Socket sock; + private const int SYSLOG_PORT = 514; + private const int RECEIVE_BUFFER_SIZE = 1024; + + private byte[] receiveBuffer = new Byte[RECEIVE_BUFFER_SIZE]; + private EndPoint remoteEndpoint = null; + private Regex msgRegex = new Regex(@" +(\<(?\d{1,3})\>){0,1} +(? + (? + (?Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s + (?
[ 0-9][0-9])\s + (?[0-9]{2})\:(?[0-9]{2})\:(?[0-9]{2}) + )\s + (? + [^ ]+? + )\s +){0,1} +(?.*) +", RegexOptions.IgnorePatternWhitespace); + + /// + /// Creates a new instance of the SyslogListener class. + /// + /// Specifies the address to listen on. IPAddress.Any will bind the listener to all available interfaces. + public SyslogListener(IPAddress listenAddress) { + this.listenAddress = listenAddress; + this.sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + } + + /// + /// Starts listening for syslog packets. + /// + public void Start() { + if (sock.IsBound) return; + sock.Bind(new IPEndPoint(listenAddress, SYSLOG_PORT)); + SetupReceive(); + } + + private void SetupReceive() { + remoteEndpoint = new IPEndPoint(IPAddress.None, 0); + sock.BeginReceiveFrom(receiveBuffer, 0, RECEIVE_BUFFER_SIZE, SocketFlags.None, ref remoteEndpoint, new AsyncCallback(DoReceiveData), sock); + } + + public event MessageReceivedEventHandler MessageReceived; + + /// + /// This internal method processes an async receive as set up by SetupReceive() + /// + private void DoReceiveData(IAsyncResult r) { + Socket sock = (Socket)r.AsyncState; + //int count = sock.EndReceive(r, out errorCode); + EndPoint ep = new IPEndPoint(IPAddress.Any, 0); + int count = 0; + try { + count = sock.EndReceiveFrom(r, ref ep); + } catch (SocketException) { + //ignore buffer overruns; .NET handles them. + } catch (ObjectDisposedException) { + //if the socket is disposed, we're shutting down, so return + return; + } + + string packet = System.Text.Encoding.ASCII.GetString(receiveBuffer, 0, count); + + Match m = msgRegex.Match(packet); + //ignore invalid messages + if (m != null && !string.IsNullOrEmpty(packet)) { + + //parse PRI section into priority + int pri; + int? priority = int.TryParse(m.Groups["PRI"].Value, out pri) ? new int?(pri) : null; + + //parse the HEADER section - contains TIMESTAMP and HOSTNAME + string hostname = null; + Nullable timestamp = null; + 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 invalid timestamps + } + } + + 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)) { + IPEndPoint ipe = (IPEndPoint)ep; + IPHostEntry he = Dns.GetHostEntry(ipe.Address); + if (he != null && !string.IsNullOrEmpty(he.HostName)) + hostname = he.HostName; + else + hostname = ep.ToString(); + } + + string message = m.Groups["MSG"].Value; + + SyslogMessage sm = new SyslogMessage(priority, timestamp.Value, hostname, message); + if (MessageReceived != null) { + MessageReceived(new MessageReceivedEventArgs(sm)); + } + } + + //after we're done processing, ready the socket for another receive. + SetupReceive(); + } + + /// + /// Stops listening and reporting syslog message packets. + /// + public void Stop() { + if (sock.IsBound) { + try { + sock.Close(); + } catch (Exception) { } + } + } + + private static int MonthNumber(string monthName) { + switch (monthName.ToLower().Substring(0,3)) { + case "jan": return 1; + case "feb": return 2; + case "mar": return 3; + case "apr": return 4; + case "may": return 5; + case "jun": return 6; + case "jul": return 7; + case "aug": return 8; + case "sep": return 9; + case "oct": return 10; + case "nov": return 11; + case "dec": return 12; + default: + throw new Exception("Unrecognised month name: " + monthName); + } + } + } +} diff --git a/Fantail.SyslogServer/SyslogService.Designer.cs b/Fantail.SyslogServer/SyslogService.Designer.cs new file mode 100644 index 0000000..094498f --- /dev/null +++ b/Fantail.SyslogServer/SyslogService.Designer.cs @@ -0,0 +1,67 @@ +/// +/// Fantail.SyslogServer +/// ==================== +/// +/// Fantail Technology Ltd ( www.fantail.net.nz ) +/// +/// Designed by Chris Guthrey & David Husselmann +/// Developed by David Husselmann for Fantail Technology Ltd +/// +/// chris@fantail.net.nz +/// david@tamix.com +/// +/// Copyright (c) 2007, Fantail Technology Ltd +/// +/// All rights reserved. +/// +/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +/// +/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +/// * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +/// +/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +/// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +/// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE +/// +namespace Fantail.SyslogServer +{ + partial class SyslogService { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() { + components = new System.ComponentModel.Container(); + this.ServiceName = "Service1"; + } + + #endregion + } +} diff --git a/Fantail.SyslogServer/SyslogService.cs b/Fantail.SyslogServer/SyslogService.cs new file mode 100644 index 0000000..16b5481 --- /dev/null +++ b/Fantail.SyslogServer/SyslogService.cs @@ -0,0 +1,102 @@ +/// +/// Fantail.SyslogServer +/// ==================== +/// +/// Fantail Technology Ltd ( www.fantail.net.nz ) +/// +/// Designed by Chris Guthrey & David Husselmann +/// Developed by David Husselmann for Fantail Technology Ltd +/// +/// chris@fantail.net.nz +/// david@tamix.com +/// +/// Copyright (c) 2007, Fantail Technology Ltd +/// +/// All rights reserved. +/// +/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +/// +/// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +/// * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +/// +/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +/// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +/// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +/// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +/// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +/// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +/// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +/// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE +/// +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.ServiceProcess; +using System.Text; +using Fantail.Libraries.Syslog; +using System.Net; + +namespace Fantail.SyslogServer { + public partial class SyslogService : ServiceBase { + + /// + /// This is where all the action really starts! + /// + /// The sequence of events is as follows: + /// + /// Create the SyslogListener object - this will listen on port 514 for syslog messages + /// Create the SqlUpdate object - this will save messages to your SQL database + /// + /// NOTE that you need to edit the new SqlUpdater for your database settings + /// + /// The MemoryBuffer holds the messages recieved by the listener and then calls the SQL update + /// in batches, so reduce load on the SQL server + /// + /// Setup event handlers for receiving new syslog messages and for handling SQL exceptions. + /// + /// and so on with starting the Fantail.SyslogServer service! + /// + /// + public SyslogService() { + InitializeComponent(); + } + + private SyslogListener syslogListener; + private SqlUpdater sqlUpdater; + private MemoryBuffer memoryBuffer; + + protected override void OnStart(string[] args) { + syslogListener = new SyslogListener(IPAddress.Any); + + /// + /// the next line needs to be edited. instead of hardcoding these details into the application + /// it would be better to store them in an XML config file or something... + /// + sqlUpdater = new SqlUpdater("server=;user=;password=;initial catalog=", "your-table-name"); + + + memoryBuffer = new MemoryBuffer(TimeSpan.FromSeconds(30), sqlUpdater); + + syslogListener.MessageReceived += new MessageReceivedEventHandler(delegate(MessageReceivedEventArgs e) { + memoryBuffer.PushMessage(e.SyslogMessage); + }); + + sqlUpdater.ExceptionThrown += new ExceptionThrownEventHandler(delegate(ExceptionThrownEventArgs e) { + EventLog.WriteEntry(EventLog.Source, e.Exception.ToString()); + }); + + syslogListener.Start(); + } + + protected override void OnStop() { + syslogListener.Stop(); + memoryBuffer.Flush(); + } + } +} diff --git a/Fantail.SyslogServer/obj/Fantail.SyslogServer.csproj.FileList.txt b/Fantail.SyslogServer/obj/Fantail.SyslogServer.csproj.FileList.txt new file mode 100644 index 0000000..ee6899d --- /dev/null +++ b/Fantail.SyslogServer/obj/Fantail.SyslogServer.csproj.FileList.txt @@ -0,0 +1,14 @@ +bin\Debug\Fantail.SyslogServer.exe +bin\Debug\Fantail.SyslogServer.pdb +obj\Debug\ResolveAssemblyReference.cache +obj\Debug\Fantail.SyslogServer.ProjectInstaller.resources +obj\Debug\Fantail.SyslogServer.csproj.GenerateResource.Cache +obj\Debug\Fantail.SyslogServer.exe +obj\Debug\Fantail.SyslogServer.pdb +bin\Release\Fantail.SyslogServer.exe +bin\Release\Fantail.SyslogServer.pdb +obj\Release\ResolveAssemblyReference.cache +obj\Release\Fantail.SyslogServer.ProjectInstaller.resources +obj\Release\Fantail.SyslogServer.csproj.GenerateResource.Cache +obj\Release\Fantail.SyslogServer.exe +obj\Release\Fantail.SyslogServer.pdb diff --git a/Fantail.SyslogServer/readme.txt b/Fantail.SyslogServer/readme.txt new file mode 100644 index 0000000..5518d37 --- /dev/null +++ b/Fantail.SyslogServer/readme.txt @@ -0,0 +1,152 @@ +Fantail.SyslogServer +==================== + +Fantail Technology Ltd ( www.fantail.net.nz ) + +Designed by Chris Guthrey & David Husselmann +Developed by David Husselmann for Fantail Technology Ltd + +chris@fantail.net.nz +david@tamix.com + +Copyright (c) 2007, Fantail Technology Ltd + + +This project is by no means fully complete. Fantail Technology Ltd has released this +project as it is under a BSD-style license so that it may be of help or use to anyone +else needing to build a C# Syslog to SQL service. + +The basic steps for building this project are: + +1) extract the ZIP file to : + + C:\Projects\Fantail\SyslogServer\SyslogServer + + If you want to stick it elsewhere, feel free to, but the solution files and such probably need to be updated. + + +2) Setup an SQL database + + 2a) If you don't already have a Microsoft SQL Server handy, you may want to download MSDE or SQLExpress + + http://www.microsoft.com/sql/prodinfo/previousversions/msde/prodinfo.mspx + or + http://msdn2.microsoft.com/en-us/express/aa718378.aspx + + Note that I haven't actually tested this code against SQLExpress, but since + it is all simple stuff, it should just work... + + + 2b) Create a database, if you can't think of a name for it, called it "FantailSysLog" + + + 2c) Create a table. Run the following SQL Statement to create the one table (just one!) that you need: + + CREATE TABLE FantailSysLog ( + Id int identity(1,1), + Facility int, + Severity int, + Timestamp datetime, + Hostname varchar(255), + Message varchar(1024) + ) + + (change "FantailSysLog" to a different table name if you wish) + + + 2d) Create a database user, and grant that user full permissions on your database and table + + +3) edit the file + + C:\Projects\Fantail\SyslogServer\SyslogServer\Fantail.SyslogServer\SyslogService.cs + + + and change the line: + + sqlUpdater = new SqlUpdater("server=;user=;password=;initial catalog=", ""); + + as follows: + this should be the network name or IP address of the machine that hosts your MS SQL Server + (if you are going to install the Fantail.SyslogService on the same machine as the SQL Server + then you can simply set this to "." or "(local)" + + this is the sql database user you created in step 2d) above + + the password you assigned to above user + + the database you created in step 2b) + + the name of the table you created in step 2c) above + + +4) build the project. This was written using Visual Studio 2005. If you don't have VS2005, you could probably + use SharpDevelop without a great deal of modification. I haven't tested this with SharpDevelop, but seeing that the + code is straightforward, it should just work... + +5) install the Service. + You will need a .NET 2 Utility called "InstallUtil". + Since the machine that you want to run this service on must already have the .NET2 framework installed, all you simply need do is + + 5a) copy your newly built executable "Fantail.SyslogServer.exe" to a location where you want to run it from. I recommend you + create the folder: C:\Program Files\Fantail + and copy it there + + 5b) open a Command Prompt (click Start menu, click on "Run...", then enter "CMD" and click the OK button) + + 5c) change directory to the location where you copied your executable to, ie: + + CD "\Program Files\Fantail" + + 5d) use InstallUtil to install the executable as a Windows Service: + + "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe" Fantail.SyslogServer.exe + + you should get a message to the effect that the service has been installed successfully. + + 5f) time to test it out! type: + + NET START "Fantail Syslog Server" + + 5g) if you get an error message, check the eventlog for clues as to what went wrong... + + EVENTVWR + + +Enjoy! + +If I get requested to, I will remove the ugly hard-coded SQL connection details, and move those settings into a Config File. +This means that a generic EXE can be used to talk to any SQL server. + +Otherwise if anyone else cares to tidy up and finish off the rough edges, please send me a copy! + +Cheers! +Chris Guthrey - chris@fantail.net.nz +Fantail Technology Ltd +www.fantail.net.nz + +=================================================================== + +Copyright (c) 2007, Fantail Technology Ltd + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + +=================================================================== diff --git a/LICENSE.TXT b/LICENSE.TXT new file mode 100644 index 0000000..c40d87d --- /dev/null +++ b/LICENSE.TXT @@ -0,0 +1,34 @@ + + Fantail.SyslogServer + ==================== + + Fantail Technology Ltd ( www.fantail.net.nz ) + + Designed by Chris Guthrey & David Husselmann + Developed by David Husselmann for Fantail Technology Ltd + + chris@fantail.net.nz + david@tamix.com + + Copyright (c) 2007, Fantail Technology Ltd + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + diff --git a/SyslogServer.sln b/SyslogServer.sln new file mode 100644 index 0000000..a7889cf --- /dev/null +++ b/SyslogServer.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fantail.SyslogServer", "Fantail.SyslogServer\Fantail.SyslogServer.csproj", "{2276C92F-8444-47B4-B3C9-AF507C41BB98}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2276C92F-8444-47B4-B3C9-AF507C41BB98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2276C92F-8444-47B4-B3C9-AF507C41BB98}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2276C92F-8444-47B4-B3C9-AF507C41BB98}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2276C92F-8444-47B4-B3C9-AF507C41BB98}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/SyslogServer.suo b/SyslogServer.suo new file mode 100644 index 0000000000000000000000000000000000000000..8b5e3e5e22240cf5fc7fa7cbf9ee0baa5f4ebd21 GIT binary patch literal 30720 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 literal 0 HcmV?d00001 diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..5518d37 --- /dev/null +++ b/readme.txt @@ -0,0 +1,152 @@ +Fantail.SyslogServer +==================== + +Fantail Technology Ltd ( www.fantail.net.nz ) + +Designed by Chris Guthrey & David Husselmann +Developed by David Husselmann for Fantail Technology Ltd + +chris@fantail.net.nz +david@tamix.com + +Copyright (c) 2007, Fantail Technology Ltd + + +This project is by no means fully complete. Fantail Technology Ltd has released this +project as it is under a BSD-style license so that it may be of help or use to anyone +else needing to build a C# Syslog to SQL service. + +The basic steps for building this project are: + +1) extract the ZIP file to : + + C:\Projects\Fantail\SyslogServer\SyslogServer + + If you want to stick it elsewhere, feel free to, but the solution files and such probably need to be updated. + + +2) Setup an SQL database + + 2a) If you don't already have a Microsoft SQL Server handy, you may want to download MSDE or SQLExpress + + http://www.microsoft.com/sql/prodinfo/previousversions/msde/prodinfo.mspx + or + http://msdn2.microsoft.com/en-us/express/aa718378.aspx + + Note that I haven't actually tested this code against SQLExpress, but since + it is all simple stuff, it should just work... + + + 2b) Create a database, if you can't think of a name for it, called it "FantailSysLog" + + + 2c) Create a table. Run the following SQL Statement to create the one table (just one!) that you need: + + CREATE TABLE FantailSysLog ( + Id int identity(1,1), + Facility int, + Severity int, + Timestamp datetime, + Hostname varchar(255), + Message varchar(1024) + ) + + (change "FantailSysLog" to a different table name if you wish) + + + 2d) Create a database user, and grant that user full permissions on your database and table + + +3) edit the file + + C:\Projects\Fantail\SyslogServer\SyslogServer\Fantail.SyslogServer\SyslogService.cs + + + and change the line: + + sqlUpdater = new SqlUpdater("server=;user=;password=;initial catalog=", ""); + + as follows: + this should be the network name or IP address of the machine that hosts your MS SQL Server + (if you are going to install the Fantail.SyslogService on the same machine as the SQL Server + then you can simply set this to "." or "(local)" + + this is the sql database user you created in step 2d) above + + the password you assigned to above user + + the database you created in step 2b) + + the name of the table you created in step 2c) above + + +4) build the project. This was written using Visual Studio 2005. If you don't have VS2005, you could probably + use SharpDevelop without a great deal of modification. I haven't tested this with SharpDevelop, but seeing that the + code is straightforward, it should just work... + +5) install the Service. + You will need a .NET 2 Utility called "InstallUtil". + Since the machine that you want to run this service on must already have the .NET2 framework installed, all you simply need do is + + 5a) copy your newly built executable "Fantail.SyslogServer.exe" to a location where you want to run it from. I recommend you + create the folder: C:\Program Files\Fantail + and copy it there + + 5b) open a Command Prompt (click Start menu, click on "Run...", then enter "CMD" and click the OK button) + + 5c) change directory to the location where you copied your executable to, ie: + + CD "\Program Files\Fantail" + + 5d) use InstallUtil to install the executable as a Windows Service: + + "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe" Fantail.SyslogServer.exe + + you should get a message to the effect that the service has been installed successfully. + + 5f) time to test it out! type: + + NET START "Fantail Syslog Server" + + 5g) if you get an error message, check the eventlog for clues as to what went wrong... + + EVENTVWR + + +Enjoy! + +If I get requested to, I will remove the ugly hard-coded SQL connection details, and move those settings into a Config File. +This means that a generic EXE can be used to talk to any SQL server. + +Otherwise if anyone else cares to tidy up and finish off the rough edges, please send me a copy! + +Cheers! +Chris Guthrey - chris@fantail.net.nz +Fantail Technology Ltd +www.fantail.net.nz + +=================================================================== + +Copyright (c) 2007, Fantail Technology Ltd + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the name of Fantail Technology Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + +===================================================================