Skip to content

Instantly share code, notes, and snippets.

@kapb14
Created October 17, 2018 07:14
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save kapb14/87255efffa173bb76cf5c1ed9db1d047 to your computer and use it in GitHub Desktop.
Save kapb14/87255efffa173bb76cf5c1ed9db1d047 to your computer and use it in GitHub Desktop.
Flask simplest realtime log file viewer
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" dir="ltr" class="uk-height-1-1">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>flasktest</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css" />
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<section class="section">
<div class="container">
<div class="columns is-centered is-mobile">
<div class="column is-muted notification is-four-fifths">
<h1 class="title">flasktest</h1>
<h2 class="subtitle">Progress example</h2>
<div id="progress"></div>
</div>
</div>
</div>
<div class="container">
<div class="columns is-centered is-mobile">
<div class="column is-dark notification is-four-fifths">
<div class="is-size-7 has-text-warning" id="display">
<ul id="display_list">
</ul>
</div>
</div>
</div>
</div>
</section>
<script type="text/javascript">
var source = new EventSource("/log");
source.onmessage = function(event) {
// $('#display').prepend(event.data);
$('#display_list').prepend('<li>'+event.data+'</li>');
if(event.data == 100){
source.close()
}
}
var source_progress = new EventSource("/progress");
source_progress.onmessage = function(event) {
$('#progress').text(event.data+'%');
$('#progress').value(event.data);
if(event.data == 100){
source_progress.close()
}
}
</script>
</body>
</html>
# -*- coding: utf-8 -*-
from flask import Flask, render_template, request, Response
from pygtail import Pygtail
import logging, os, sys, time
app = Flask(__name__)
app.config["SECRET_KEY"] = "SECRETKEYSECRETKEYSECRETKEYSECRETKEYSECRETKEY"
app.config["DEBUG"] = os.environ.get("FLASK_DEBUG", True)
app.config["JSON_AS_ASCII"] = False
LOG_FILE = 'app.log'
log = logging.getLogger('__name__')
logging.basicConfig(filename=LOG_FILE, level=logging.DEBUG)
@app.route('/')
def entry_point():
log.info("route =>'/env' - hit!")
return render_template('base.html')
@app.route('/progress')
def progress():
def generate():
x = 0
while x <= 100:
yield "data:" + str(x) + "\n\n"
x = x + 10
time.sleep(0.5)
return Response(generate(), mimetype= 'text/event-stream')
@app.route('/log')
def progress_log():
def generate():
for line in Pygtail(LOG_FILE, every_n=1):
yield "data:" + str(line) + "\n\n"
time.sleep(0.5)
return Response(generate(), mimetype= 'text/event-stream')
@app.route('/env')
def show_env():
log.info("route =>'/env' - hit")
env = {}
for k,v in request.environ.items():
env[k] = str(v)
log.info("route =>'/env' [env]:\n%s" % env)
return env
if __name__ == '__main__':
app.run(debug=True)
@bjenmonk
Copy link

bjenmonk commented Nov 3, 2022

Appreciate it if you can show me how to initiate start of tailing on button click

@macrokernel
Copy link

macrokernel commented Jan 4, 2023

Thanks for publishing this! The example is mostly working for me. Though there is an issue when a log file is growing faster than 1 message per second - the displayed log is lagging behind the log file. Reducing sleep time to 0.1 fixed the issue.

@luozhijian
Copy link

thanks for the sharing. It works for me. When I first copied the code, I missed "data:" and "\n\n". It is important the line should be:
yield "data:" + str(line) + "\n\n"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment