diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go
index ba5d657466699974f475dcf482862bc87e257892..61c5617a1ea9c69e99791842654783ac52accbe8 100644
--- a/cmd/ipfs/daemon.go
+++ b/cmd/ipfs/daemon.go
@@ -285,6 +285,7 @@ func serveHTTPApi(req cmds.Request) (error, <-chan error) {
 		corehttp.VersionOption(),
 		defaultMux("/debug/vars"),
 		defaultMux("/debug/pprof/"),
+		corehttp.LogOption(),
 	}
 
 	if len(cfg.Gateway.RootRedirect) > 0 {
diff --git a/core/corehttp/logs.go b/core/corehttp/logs.go
new file mode 100644
index 0000000000000000000000000000000000000000..4cdf529ad099e982205148560c4af6cb449d7ac4
--- /dev/null
+++ b/core/corehttp/logs.go
@@ -0,0 +1,42 @@
+package corehttp
+
+import (
+	"io"
+	"net/http"
+
+	core "github.com/ipfs/go-ipfs/core"
+	"github.com/ipfs/go-ipfs/thirdparty/eventlog"
+)
+
+type writeErrNotifier struct {
+	w    io.Writer
+	errs chan error
+}
+
+func newWriteErrNotifier(w io.Writer) (io.Writer, <-chan error) {
+	ch := make(chan error, 1)
+	return &writeErrNotifier{
+		w:    w,
+		errs: ch,
+	}, ch
+}
+
+func (w *writeErrNotifier) Write(b []byte) (int, error) {
+	n, err := w.w.Write(b)
+	if err != nil {
+		w.errs <- err
+	}
+	return n, err
+}
+
+func LogOption() ServeOption {
+	return func(n *core.IpfsNode, mux *http.ServeMux) (*http.ServeMux, error) {
+		mux.HandleFunc("/logs", func(w http.ResponseWriter, r *http.Request) {
+			w.WriteHeader(200)
+			wnf, errs := newWriteErrNotifier(w)
+			eventlog.WriterGroup.AddWriter(wnf)
+			<-errs
+		})
+		return mux, nil
+	}
+}
diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go
index d35a3525c5ccd1bba27cf64e8e7bb18cdb7faeaa..4c4735396221c34e8ea236cffe3a74a2a9de476b 100644
--- a/repo/fsrepo/fsrepo.go
+++ b/repo/fsrepo/fsrepo.go
@@ -368,13 +368,7 @@ func (r *FSRepo) openDatastore() error {
 func configureEventLoggerAtRepoPath(c *config.Config, repoPath string) {
 	eventlog.Configure(eventlog.LevelInfo)
 	eventlog.Configure(eventlog.LdJSONFormatter)
-	rotateConf := eventlog.LogRotatorConfig{
-		Filename:   path.Join(repoPath, "logs", "events.log"),
-		MaxSizeMB:  c.Log.MaxSizeMB,
-		MaxBackups: c.Log.MaxBackups,
-		MaxAgeDays: c.Log.MaxAgeDays,
-	}
-	eventlog.Configure(eventlog.OutputRotatingLogFile(rotateConf))
+	eventlog.Configure(eventlog.Output(eventlog.WriterGroup))
 }
 
 // Close closes the FSRepo, releasing held resources.
diff --git a/thirdparty/eventlog/option.go b/thirdparty/eventlog/option.go
index 6d297bb3bd953eff6820f31d687e875b13a4d432..bf5219d60e5ee97848f23db9aeee029240b3e884 100644
--- a/thirdparty/eventlog/option.go
+++ b/thirdparty/eventlog/option.go
@@ -18,6 +18,8 @@ func init() {
 	Configure(LevelError)
 }
 
+var WriterGroup = new(MirrorWriter)
+
 type Option func()
 
 // Configure applies the provided options sequentially from left to right
diff --git a/thirdparty/eventlog/writer.go b/thirdparty/eventlog/writer.go
new file mode 100644
index 0000000000000000000000000000000000000000..5397fc6853262f8f57e80a5fde07f29e45c998ff
--- /dev/null
+++ b/thirdparty/eventlog/writer.go
@@ -0,0 +1,31 @@
+package eventlog
+
+import (
+	"io"
+	"sync"
+)
+
+type MirrorWriter struct {
+	writers []io.Writer
+	lk      sync.Mutex
+}
+
+func (mw *MirrorWriter) Write(b []byte) (int, error) {
+	mw.lk.Lock()
+	var filter []io.Writer
+	for _, w := range mw.writers {
+		_, err := w.Write(b)
+		if err == nil {
+			filter = append(filter, w)
+		}
+	}
+	mw.writers = filter
+	mw.lk.Unlock()
+	return len(b), nil
+}
+
+func (mw *MirrorWriter) AddWriter(w io.Writer) {
+	mw.lk.Lock()
+	mw.writers = append(mw.writers, w)
+	mw.lk.Unlock()
+}