diff --git a/.dockerignore b/.dockerignore
index 5cb0969..375b896 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,11 +1,9 @@
# Github
.github
.gitignore
-docs
+docs
*.md
-Dockerfile
-Dockerfile.local
-docker-compose.yml
+docker-compose/*
# Logs
logs
diff --git a/README.md b/README.md
index 26700d6..5a02dd3 100644
--- a/README.md
+++ b/README.md
@@ -46,7 +46,9 @@ Available:
* [Combine custom actions](#Combinecustomactions)
* [Change default Queries/Request commands](#ChangedefaultQueriesRequestcommands)
* [Loggers](#Loggers)
+ * [Format](#Format)
* [Seq](#Seq)
+ * [ELK](#ELK)
* [Setting up](#Settingup)
* [Docker](#Docker)
* [Docker-Compose](#Docker-Compose)
@@ -243,11 +245,20 @@ HTTP/1.1 401 Unauthorized
| Environment | CLI | Default |
|------------------------------------|------------------------------------|--------------------|
| LOGS__APP | --logs:app | `echo-server` |
-| LOGS__LEVEL | --logs:level | `debug` |
+| LOGS__LEVEL | --logs:level | `debug` |
+| LOGS__FORMAT | --logs:format | `default` |
+
+### Format
+
+| LOG FORMAT | DESCRIPTION |
+|-------------------|-----------------------------------------------------------------------------|
+| default | Combine `line` & `object` |
+| line | Simple `Fri, 22 Jan 2021 10:45:20 GMT | [GET] - http://localhost:8080/path` |
+| object | JSON `{ "host": {}, http: {}, request: {}}` |
### Seq
-![seq](https://ealenn.github.io/Echo-Server/assets/images/seq.png)
+[Full example](https://github.com/Ealenn/Echo-Server/tree/master/docker-compose) - [Documentation](https://ealenn.github.io/Echo-Server/pages/quick-start/docker-compose.html)
| Environment | CLI | Default |
|------------------------------------|------------------------------------|--------------------|
@@ -256,6 +267,10 @@ HTTP/1.1 401 Unauthorized
| LOGS__SEQ__KEY | --logs:seq:key | ` ` |
| LOGS__SEQ__LEVEL | --logs:seq:level | `info` |
+### ELK
+
+[Full example](https://github.com/Ealenn/Echo-Server/tree/master/docker-compose) - [Documentation](https://ealenn.github.io/Echo-Server/pages/quick-start/docker-compose.html)
+
## Setting up
### Docker
@@ -285,7 +300,6 @@ services:
```yaml
version: "3"
-
services:
echo:
image: ealen/echo-server
diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 0000000..673a07d
--- /dev/null
+++ b/codecov.yml
@@ -0,0 +1,7 @@
+coverage:
+ range: 90..100
+ round: down
+ precision: 2
+ignore:
+ - "test/*"
+ - "src/middlewares/logMiddleware.js"
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index b585083..0000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-version: "3"
-
-services:
- echo:
- build:
- context: .
- dockerfile: Dockerfile.local
- environment:
- PORT: 80
- LOGS__SEQ__ENABLED: "true"
- LOGS__SEQ__SERVER: "http://seq:5341"
- ports:
- - 8080:80
- networks:
- - backend
-
- seq:
- image: datalust/seq:latest
- environment:
- ACCEPT_EULA: "Y"
- ports:
- - 8081:80
- - 5341:5341
- networks:
- - backend
-
-networks:
- backend:
\ No newline at end of file
diff --git a/Dockerfile.local b/docker-compose/Dockerfile.local
similarity index 100%
rename from Dockerfile.local
rename to docker-compose/Dockerfile.local
diff --git a/docker-compose/ELK/docker-compose.yml b/docker-compose/ELK/docker-compose.yml
new file mode 100644
index 0000000..e9aca50
--- /dev/null
+++ b/docker-compose/ELK/docker-compose.yml
@@ -0,0 +1,48 @@
+version: "3"
+services:
+ # ----------------------------------
+ # ECHO-SERVER
+ # ----------------------------------
+ echo:
+ build:
+ context: ../../
+ dockerfile: docker-compose/Dockerfile.local
+ restart: unless-stopped
+ logging:
+ driver: syslog
+ options:
+ syslog-address: "tcp://localhost:8089"
+ environment:
+ - "LOGS__FORMAT=object"
+ depends_on:
+ - logstash
+ ports:
+ - 3000:80
+
+ # ----------------------------------
+ # ELK
+ # ----------------------------------
+ elasticsearch:
+ image: elasticsearch:7.7.0
+ hostname: elasticsearch
+ restart: unless-stopped
+ environment:
+ - "discovery.type=single-node"
+ kibana:
+ image: kibana:7.7.0
+ hostname: kibana
+ restart: unless-stopped
+ depends_on:
+ - elasticsearch
+ ports:
+ - 3010:5601
+ logstash:
+ image: logstash:7.7.0
+ hostname: logstash
+ restart: unless-stopped
+ volumes:
+ - ./logstash:/usr/share/logstash/pipeline/
+ depends_on:
+ - elasticsearch
+ ports:
+ - 8089:8089
diff --git a/docker-compose/ELK/logstash/logstash.conf b/docker-compose/ELK/logstash/logstash.conf
new file mode 100755
index 0000000..f2a9dd6
--- /dev/null
+++ b/docker-compose/ELK/logstash/logstash.conf
@@ -0,0 +1,9 @@
+input {
+ tcp {
+ port => 8089
+ }
+}
+
+output {
+ elasticsearch { hosts => ["elasticsearch:9200"] }
+}
\ No newline at end of file
diff --git a/docker-compose/SEQ/docker-compose.yml b/docker-compose/SEQ/docker-compose.yml
new file mode 100644
index 0000000..8a14ea2
--- /dev/null
+++ b/docker-compose/SEQ/docker-compose.yml
@@ -0,0 +1,27 @@
+version: "3"
+services:
+ # ----------------------------------
+ # ECHO-SERVER
+ # ----------------------------------
+ echo:
+ build:
+ context: ../../
+ dockerfile: ../Dockerfile.local
+ restart: unless-stopped
+ environment:
+ PORT: 80
+ LOGS__SEQ__ENABLED: "true"
+ LOGS__SEQ__SERVER: "http://seq:5341"
+ ports:
+ - 3000:80
+
+ # ----------------------------------
+ # SEQ
+ # ----------------------------------
+ seq:
+ image: datalust/seq:latest
+ restart: unless-stopped
+ environment:
+ ACCEPT_EULA: "Y"
+ ports:
+ - 3010:80
diff --git a/docs/pages/configuration/loggers.md b/docs/pages/configuration/loggers.md
index 8a8feed..6f0b3ba 100644
--- a/docs/pages/configuration/loggers.md
+++ b/docs/pages/configuration/loggers.md
@@ -23,6 +23,15 @@ nav_order: 2
| LOGS__IGNORE__PING | --logs:ignore:ping | `false` |
| LOGS__APP | --logs:app | `echo-server` |
| LOGS__LEVEL | --logs:level | `debug` |
+| LOGS__FORMAT | --logs:format | `default` |
+
+### Format
+
+| LOG FORMAT | DESCRIPTION |
+|-------------------|-----------------------------------------------------------------------------|
+| default | Combine `line` and `object` |
+| line | Simple `Fri, 22 Jan 2021 10:45:20 GMT | [GET] - http://localhost:8080/path` |
+| object | JSON `{ "host": {}, http: {}, request: {}}` |
## Seq
diff --git a/docs/pages/quick-start/docker-compose.md b/docs/pages/quick-start/docker-compose.md
index d9f96a0..f5bdea0 100644
--- a/docs/pages/quick-start/docker-compose.md
+++ b/docs/pages/quick-start/docker-compose.md
@@ -51,26 +51,106 @@ services:
[More information](https://ealenn.github.io/Echo-Server/pages/configuration/loggers)
+### Seq
+
```yaml
version: "3"
services:
+ # ----------------------------------
+ # ECHO-SERVER
+ # ----------------------------------
echo:
image: ealen/echo-server:{{ site.github.releases[0].tag_name }}
- environment:
+ restart: unless-stopped
+ environment:
PORT: 80
LOGS__SEQ__ENABLED: "true"
LOGS__SEQ__SERVER: "http://seq:5341"
- ports:
+ ports:
- 3000:80
+ # ----------------------------------
+ # SEQ
+ # ----------------------------------
seq:
- image: datalust/seq:{{ site.github.releases[0].tag_name }}
- environment:
+ image: datalust/seq:latest
+ restart: unless-stopped
+ environment:
ACCEPT_EULA: "Y"
ports:
- 3010:80
```
+> - Echo-Server : [http://localhost:3000](http://localhost:3000)
+> - Seq : [http://localhost:3010](http://localhost:3010)
+
+### ELK
+
+```conf
+# ./logstash/logstash.conf
+input {
+ tcp {
+ port => 8089
+ }
+}
+
+output {
+ elasticsearch { hosts => ["elasticsearch:9200"] }
+}
+```
+
+```yaml
+version: "3"
+services:
+ # ----------------------------------
+ # ECHO-SERVER
+ # ----------------------------------
+ echo:
+ image: ealen/echo-server:{{ site.github.releases[0].tag_name }}
+ restart: unless-stopped
+ logging:
+ driver: syslog
+ options:
+ syslog-address: "tcp://localhost:8089"
+ environment:
+ - "LOGS__FORMAT=object"
+ depends_on:
+ - logstash
+ ports:
+ - 3000:80
+
+ # ----------------------------------
+ # ELK
+ # ----------------------------------
+ elasticsearch:
+ image: elasticsearch:7.7.0
+ hostname: elasticsearch
+ restart: unless-stopped
+ environment:
+ - "discovery.type=single-node"
+ kibana:
+ image: kibana:7.7.0
+ hostname: kibana
+ restart: unless-stopped
+ depends_on:
+ - elasticsearch
+ ports:
+ - 3010:5601
+ logstash:
+ image: logstash:7.7.0
+ hostname: logstash
+ restart: unless-stopped
+ volumes:
+ - ./logstash:/usr/share/logstash/pipeline/
+ depends_on:
+ - elasticsearch
+ ports:
+ - 8089:8089
+```
+
+> - Echo-Server : [http://localhost:3000](http://localhost:3000)
+> - Kibana : [http://localhost:3010](http://localhost:3010)
+
## Examples
{% include_relative includes/section-examples.md host="localhost:3000" %}
\ No newline at end of file
diff --git a/src/global.json b/src/global.json
index 939ba20..4e884c6 100644
--- a/src/global.json
+++ b/src/global.json
@@ -3,6 +3,7 @@
"logs": {
"app": "echo-server",
"level": "debug",
+ "format": "default",
"ignore": {
"ping": false
},
diff --git a/src/middlewares/logMiddleware.js b/src/middlewares/logMiddleware.js
index 05f19dd..52aaac9 100644
--- a/src/middlewares/logMiddleware.js
+++ b/src/middlewares/logMiddleware.js
@@ -25,12 +25,28 @@ const log = bunyan.createLogger({
module.exports = (req, res, next) => {
if (req.originalUrl != "/ping" || !config.get('logs:ignore:ping')) {
- log.info({
- host: require('../response/host')(req),
- http: require('../response/http')(req),
- request: require('../response/request')(req),
- environment: require('../response/environment')(req)
- }, `${new Date().toUTCString()} | [${req.method}] - ${req.protocol}://${req.get('host')}${req.originalUrl}`);
+ switch (config.get('logs:format'))
+ {
+ case "line":
+ log.info(`${new Date().toUTCString()} | [${req.method}] - ${req.protocol}://${req.get('host')}${req.originalUrl}`);
+ break;
+ case "object":
+ log.info({
+ host: require('../response/host')(req),
+ http: require('../response/http')(req),
+ request: require('../response/request')(req),
+ environment: require('../response/environment')(req)
+ });
+ break;
+ default:
+ log.info({
+ host: require('../response/host')(req),
+ http: require('../response/http')(req),
+ request: require('../response/request')(req),
+ environment: require('../response/environment')(req)
+ }, `${new Date().toUTCString()} | [${req.method}] - ${req.protocol}://${req.get('host')}${req.originalUrl}`);
+ break;
+ }
}
next();
}
\ No newline at end of file
diff --git a/test/logs.js b/test/logs.js
new file mode 100644
index 0000000..676c87a
--- /dev/null
+++ b/test/logs.js
@@ -0,0 +1,74 @@
+const assert = require('assert');
+const request = require('supertest');
+
+process.env.LOGS__LEVEL = "error";
+
+const availableConfiguration = ["default", "line", "object"];
+
+availableConfiguration.forEach(configuration => {
+ process.env.LOGS__FORMAT = configuration;
+ describe('Logs with ' + configuration, function () {
+ var server;
+ beforeEach(function () {
+ server = require('../src/app');
+ });
+ afterEach(function () {
+ server.close();
+ });
+ it('GET', function test(done) {
+ request(server)
+ .get('/')
+ .expect(function (res) {
+ assert.strictEqual(res.body.http.method, 'GET')
+ assert.strictEqual(res.body.http.protocol, 'http')
+ assert.strictEqual(res.body.http.originalUrl, '/')
+ assert.strictEqual(res.body.http.baseUrl, '')
+ })
+ .expect(200, done);
+ });
+ it('POST', function test(done) {
+ request(server)
+ .post('/')
+ .expect(function (res) {
+ assert.strictEqual(res.body.http.method, 'POST')
+ assert.strictEqual(res.body.http.protocol, 'http')
+ assert.strictEqual(res.body.http.originalUrl, '/')
+ assert.strictEqual(res.body.http.baseUrl, '')
+ })
+ .expect(200, done);
+ });
+ it('PUT', function test(done) {
+ request(server)
+ .put('/')
+ .expect(function (res) {
+ assert.strictEqual(res.body.http.method, 'PUT')
+ assert.strictEqual(res.body.http.protocol, 'http')
+ assert.strictEqual(res.body.http.originalUrl, '/')
+ assert.strictEqual(res.body.http.baseUrl, '')
+ })
+ .expect(200, done);
+ });
+ it('PATCH', function test(done) {
+ request(server)
+ .patch('/')
+ .expect(function (res) {
+ assert.strictEqual(res.body.http.method, 'PATCH')
+ assert.strictEqual(res.body.http.protocol, 'http')
+ assert.strictEqual(res.body.http.originalUrl, '/')
+ assert.strictEqual(res.body.http.baseUrl, '')
+ })
+ .expect(200, done);
+ });
+ it('DELETE', function test(done) {
+ request(server)
+ .delete('/')
+ .expect(function (res) {
+ assert.strictEqual(res.body.http.method, 'DELETE')
+ assert.strictEqual(res.body.http.protocol, 'http')
+ assert.strictEqual(res.body.http.originalUrl, '/')
+ assert.strictEqual(res.body.http.baseUrl, '')
+ })
+ .expect(200, done);
+ });
+ });
+});