diff --git a/production/tail/docker-compose.yml b/production/tail/docker-compose.yml new file mode 100644 index 0000000..bede119 --- /dev/null +++ b/production/tail/docker-compose.yml @@ -0,0 +1,26 @@ +version: '2' + +services: + tail: + image: node:12-slim + restart: always + hostname: tail + container_name: tail + working_dir: /tail + entrypoint: + - node + - index + volumes: + - ./tail:/tail + - /opt/docker/production/nginx/logs/access.log:/access.log:ro + - /opt/docker/production/fail2ban/fail2ban.log:/fail2ban.log:ro + networks: + mynet: + ipv4_address: 172.28.0.101 + +networks: + mynet: + driver: bridge + ipam: + config: + - subnet: 172.28.0.0/24 diff --git a/production/tail/tail/index.js b/production/tail/tail/index.js new file mode 100644 index 0000000..e8876c5 --- /dev/null +++ b/production/tail/tail/index.js @@ -0,0 +1,41 @@ +const http = require('http'), + express = require('express'), + app = express(), + ts = require('tail-stream'), + Transform = require('stream').Transform, + server = http.createServer(app).listen(80, () => { + console.log(`Listening on: ${server.address().address}:${server.address().port}`) + })/*.on('connection', socket => { + socket.setTimeout(300 * 1000) + })*/ + +server.keepAliveTimeout = 300 * 1000 +server.timeout = 300 * 1000 + +app.disable('x-powered-by').use('/tail', (req, res, next) => { + res.header('Content-Type', 'text/event-stream') + res.header('Connection', 'keep-alive') + res.header('Cache-Control', 'no-cache') + const transform = new Transform({ + transform: (chunk, enc, cb) => { + cb(null, Buffer.from(chunk.toString().replace(/\n/, '\n\ndata: '))) + } + }) + res.on('close', () => { + transform.destroy() + }) + ts.createReadStream('/access.log', { beginAt: 'end' }).pipe(transform).pipe(res) +}).use('/f2b', (req, res, next) => { + res.header('Content-Type', 'text/event-stream') + res.header('Connection', 'keep-alive') + res.header('Cache-Control', 'no-cache') + const transform = new Transform({ + transform: (chunk, enc, cb) => { + cb(null, Buffer.from(chunk.toString().replace(/\n/, '\n\ndata: '))) + } + }) + res.on('close', () => { + transform.destroy() + }) + ts.createReadStream('/fail2ban.log', { beginAt: 'end' }).pipe(transform).pipe(res) +}).use(express.static(__dirname + '/public')) diff --git a/production/tail/tail/package.json b/production/tail/tail/package.json new file mode 100644 index 0000000..6aa3084 --- /dev/null +++ b/production/tail/tail/package.json @@ -0,0 +1,12 @@ +{ + "name": "tail", + "version": "1.0.0", + "description": "", + "main": "index.js", + "dependencies": { + "express": "*", + "tail-stream": "*" + }, + "author": "", + "license": "MIT" +} diff --git a/production/tail/tail/public/fail2ban.html b/production/tail/tail/public/fail2ban.html new file mode 100644 index 0000000..38588a2 --- /dev/null +++ b/production/tail/tail/public/fail2ban.html @@ -0,0 +1,27 @@ + + +
+ + + +