tail
Este commit está contenido en:
26
production/tail/docker-compose.yml
Archivo normal
26
production/tail/docker-compose.yml
Archivo normal
@@ -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
|
||||||
41
production/tail/tail/index.js
Archivo normal
41
production/tail/tail/index.js
Archivo normal
@@ -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'))
|
||||||
12
production/tail/tail/package.json
Archivo normal
12
production/tail/tail/package.json
Archivo normal
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "tail",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"dependencies": {
|
||||||
|
"express": "*",
|
||||||
|
"tail-stream": "*"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
||||||
27
production/tail/tail/public/fail2ban.html
Archivo normal
27
production/tail/tail/public/fail2ban.html
Archivo normal
@@ -0,0 +1,27 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script>
|
||||||
|
window.onload = function () {
|
||||||
|
var source = new EventSource('/f2b'),
|
||||||
|
timeout,
|
||||||
|
scroll = true
|
||||||
|
source.onmessage = function (event) {
|
||||||
|
document.getElementById('result').innerHTML += '<li>' + event.data.replace(/ Ban/i,' <span style="color:white;background-color:black;">Ban</span>') + '</li>'
|
||||||
|
timeout ? window.clearTimeout(timeout) : null
|
||||||
|
timeout = window.setTimeout(window.location.reload, 4 * 60 * 1000, false)
|
||||||
|
document.body.addEventListener("click", function(event) {
|
||||||
|
scroll = scroll ? false : true
|
||||||
|
})
|
||||||
|
scroll ? window.scrollTo(0,document.body.scrollHeight) : null
|
||||||
|
}
|
||||||
|
source.onerror = function (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ol id="result"></ol>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
24
production/tail/tail/public/index.html
Archivo normal
24
production/tail/tail/public/index.html
Archivo normal
@@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script>
|
||||||
|
window.onload = function () {
|
||||||
|
var source = new EventSource('/tail'),
|
||||||
|
scroll = true
|
||||||
|
source.onmessage = function (event) {
|
||||||
|
document.getElementById('result').innerHTML += '<li>' + event.data.replace(/hatthieves/i,'<span style="color:white;background-color:black;">hatthieves</span>') + '</li>'
|
||||||
|
document.body.addEventListener("click", function(event) {
|
||||||
|
scroll = scroll ? false : true
|
||||||
|
})
|
||||||
|
scroll ? window.scrollTo(0,document.body.scrollHeight) : null
|
||||||
|
}
|
||||||
|
source.onerror = function (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ol id="result"></ol>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Referencia en una nueva incidencia
Block a user