Merge pull request #46 from didip/master

SyslogHook
diff --git a/README.md b/README.md
index a171763..3a6aced 100644
--- a/README.md
+++ b/README.md
@@ -205,10 +205,12 @@
 import (
   log "github.com/Sirupsen/logrus"
   "github.com/Sirupsen/logrus/hooks/airbrake"
+  "github.com/Sirupsen/logrus/hooks/syslog"
 )
 
 func init() {
   log.AddHook(new(logrus_airbrake.AirbrakeHook))
+  log.AddHook(logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, ""))
 }
 ```
 
@@ -216,6 +218,10 @@
   Send errors to an exception tracking service compatible with the Airbrake API.
   Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes.
 
+* [`github.com/Sirupsen/logrus/hooks/syslog`](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go).
+  Send errors to remote syslog server.
+  Uses standard library `log/syslog` behind the scenes.
+
 #### Level logging
 
 Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic.
diff --git a/hooks/syslog/README.md b/hooks/syslog/README.md
new file mode 100644
index 0000000..cd706bc
--- /dev/null
+++ b/hooks/syslog/README.md
@@ -0,0 +1,20 @@
+# Syslog Hooks for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/>
+
+## Usage
+
+```go
+import (
+  "log/syslog"
+  "github.com/Sirupsen/logrus"
+  "github.com/Sirupsen/logrus/hooks/syslog"
+)
+
+func main() {
+  log       := logrus.New()
+  hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
+
+  if err == nil {
+    log.Hooks.Add(hook)
+  }
+}
+```
\ No newline at end of file
diff --git a/hooks/syslog/syslog.go b/hooks/syslog/syslog.go
new file mode 100644
index 0000000..2a18ce6
--- /dev/null
+++ b/hooks/syslog/syslog.go
@@ -0,0 +1,59 @@
+package logrus_syslog
+
+import (
+	"fmt"
+	"github.com/Sirupsen/logrus"
+	"log/syslog"
+	"os"
+)
+
+// SyslogHook to send logs via syslog.
+type SyslogHook struct {
+	Writer        *syslog.Writer
+	SyslogNetwork string
+	SyslogRaddr   string
+}
+
+// Creates a hook to be added to an instance of logger. This is called with
+// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")`
+// `if err == nil { log.Hooks.Add(hook) }`
+func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
+	w, err := syslog.Dial(network, raddr, priority, tag)
+	return &SyslogHook{w, network, raddr}, err
+}
+
+func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
+	line, err := entry.String()
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
+		return err
+	}
+
+	switch entry.Data["level"] {
+	case "panic":
+		return hook.Writer.Crit(line)
+	case "fatal":
+		return hook.Writer.Crit(line)
+	case "error":
+		return hook.Writer.Err(line)
+	case "warn":
+		return hook.Writer.Warning(line)
+	case "info":
+		return hook.Writer.Info(line)
+	case "debug":
+		return hook.Writer.Debug(line)
+	default:
+		return nil
+	}
+}
+
+func (hook *SyslogHook) Levels() []logrus.Level {
+	return []logrus.Level{
+		logrus.PanicLevel,
+		logrus.FatalLevel,
+		logrus.ErrorLevel,
+		logrus.WarnLevel,
+		logrus.InfoLevel,
+		logrus.DebugLevel,
+	}
+}
diff --git a/hooks/syslog/syslog_test.go b/hooks/syslog/syslog_test.go
new file mode 100644
index 0000000..42762dc
--- /dev/null
+++ b/hooks/syslog/syslog_test.go
@@ -0,0 +1,26 @@
+package logrus_syslog
+
+import (
+	"github.com/Sirupsen/logrus"
+	"log/syslog"
+	"testing"
+)
+
+func TestLocalhostAddAndPrint(t *testing.T) {
+	log := logrus.New()
+	hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
+
+	if err != nil {
+		t.Errorf("Unable to connect to local syslog.")
+	}
+
+	log.Hooks.Add(hook)
+
+	for _, level := range hook.Levels() {
+		if len(log.Hooks[level]) != 1 {
+			t.Errorf("SyslogHook was not added. The length of log.Hooks[%v]: %v", level, len(log.Hooks[level]))
+		}
+	}
+
+	log.Info("Congratulations!")
+}