Skip to content

Commit 54badc5

Browse files
committed
Merge pull request #2982 from rjocoleman/platform-drain
Proposal: Platform-wide log drain
2 parents b451f8a + 571f6f5 commit 54badc5

3 files changed

Lines changed: 79 additions & 2 deletions

File tree

docs/managing_deis/platform_logging.rst

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,19 @@ and sends their logs to ``/deis/logs/host`` and ``/deis/logs/port``.
1616
when a client runs ``deis logs``. This component publishes its host and port to ``/deis/logs/host``
1717
and ``/deis/logs/port``, and is typically the service which consumes logs from ``deis-logspout``.
1818

19-
Routing logs to a custom location
20-
---------------------------------
19+
Application log drain
20+
---------------------
21+
22+
Application logs can be drained to an external syslog server (or compatible service such as Logstash, Papertrail, Splunk etc).
23+
24+
.. code-block:: console
25+
26+
$ deisctl config logs set drain=syslog://logs2.papertrailapp.com:23654
27+
28+
This will send all application logs - there is currently no way to drain logs per application.
29+
30+
Routing host logs to a custom location
31+
--------------------------------------
2132

2233
Logging to an external location can be achieved without modifying the log flow within Deis -
2334
we can simply send the master journal on a CoreOS host using ``ncat``. For example, if I'm using the

logger/drain/drain.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package drain
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"net"
7+
"net/url"
8+
"os"
9+
10+
"github.com/coreos/go-etcd/etcd"
11+
)
12+
13+
func GetDrain() string {
14+
host := getopt("HOST", "127.0.0.1")
15+
16+
etcdPort := getopt("ETCD_PORT", "4001")
17+
etcdPath := getopt("ETCD_PATH", "/deis/logs")
18+
19+
client := etcd.NewClient([]string{"http://" + host + ":" + etcdPort})
20+
21+
s, err := client.Get(etcdPath+"/drain", true, false)
22+
if err != nil {
23+
return ""
24+
}
25+
26+
return s.Node.Value
27+
}
28+
29+
func SendToDrain(m string, drain string) error {
30+
u, err := url.Parse(drain)
31+
if err != nil {
32+
log.Fatal(err)
33+
}
34+
uri := u.Host + u.Path
35+
switch u.Scheme {
36+
case "syslog":
37+
sendToSyslogDrain(m, uri)
38+
default:
39+
log.Println(u.Scheme + " drain type is not implemented.")
40+
}
41+
return nil
42+
}
43+
44+
func sendToSyslogDrain(m string, drain string) error {
45+
conn, err := net.Dial("udp", drain)
46+
if err != nil {
47+
log.Fatal(err)
48+
}
49+
defer conn.Close()
50+
fmt.Fprintf(conn, m)
51+
return nil
52+
}
53+
54+
func getopt(name, dfault string) string {
55+
value := os.Getenv(name)
56+
if value == "" {
57+
value = dfault
58+
}
59+
return value
60+
}

logger/syslogd/syslogd.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"regexp"
1010

1111
"github.com/deis/deis/logger/syslog"
12+
13+
"github.com/deis/deis/logger/drain"
1214
)
1315

1416
const logRoot = "/data/logs"
@@ -82,6 +84,10 @@ func (h *handler) mainLoop() {
8284
if m == nil {
8385
break
8486
}
87+
d := drain.GetDrain()
88+
if d != "" {
89+
drain.SendToDrain(m.String(), d)
90+
}
8591
err := writeToDisk(m)
8692
if err != nil {
8793
log.Println(err)

0 commit comments

Comments
 (0)