Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions deployment/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ docker logs webserver
docker logs dbserver # usually less interesting
```

Finally, the application-level logs produced by LNT (which are usually the most interesting)
can be inspected under `/var/log/lnt`.

The database is stored in an independent EBS storage that gets attached and detached
to/from the EC2 instance when it is created/destroyed, but the EBS storage has its own
independent life cycle (because we want the data to outlive any specific EC2 instance).
Expand Down
7 changes: 0 additions & 7 deletions deployment/ec2-volume-mapping.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,6 @@ volumes:
type: none
device: /var/lib/lnt

logs:
driver: local
driver_opts:
o: bind
type: none
device: /var/log/lnt

database:
driver: local
driver_opts:
Expand Down
1 change: 0 additions & 1 deletion deployment/on-ec2-boot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ fi
echo "Creating necessary filesystem hierarchy on the persistent volume"
mkdir -p /mnt/lnt-persistent-state/var/lib/lnt
mkdir -p /mnt/lnt-persistent-state/var/lib/postgresql
mkdir -p /var/log/lnt # logs are not persisted

echo "Linking locations inside the persistent volume to the expected locations on the instance"
if [[ ! -e "/var/lib/lnt" ]]; then
Expand Down
2 changes: 0 additions & 2 deletions docker/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ services:
condition: on-failure
volumes:
- instance:/var/lib/lnt
- logs:/var/log/lnt
# Only expose this port to the internal Docker network, but not to
# the outside world.
expose:
Expand Down Expand Up @@ -100,7 +99,6 @@ services:

volumes:
instance:
logs:
database:

secrets:
Expand Down
3 changes: 1 addition & 2 deletions docker/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,5 @@ exec gunicorn lnt_wsgi:application \
--workers 8 \
--timeout 300 \
--name lnt_server \
--log-file /var/log/lnt/lnt.log \
--access-logfile /var/log/lnt/gunicorn_access.log \
--access-logfile - \
--max-requests 250000
7 changes: 2 additions & 5 deletions docker/lnt.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@
# /var/lib/lnt
# The actual LNT instance data (schema files, configuration files, etc).
#
# /var/log/lnt
# Log files for the instance.
#

FROM python:3.10-alpine AS builder

Expand All @@ -50,8 +47,8 @@ RUN apk update && apk add --no-cache libpq

COPY --from=builder /root/.local /root/.local

# Prepare volumes that will be used by the server
VOLUME /var/lib/lnt /var/log/lnt
# Prepare volume that will be used by the server
VOLUME /var/lib/lnt

# Set up the actual entrypoint that gets run when the container starts.
COPY docker/docker-entrypoint.sh docker/lnt-wait-db /usr/local/bin/
Expand Down
2 changes: 1 addition & 1 deletion lnt/lnttool/runserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def action_runserver(instance_path, hostname, port, reloader, debugger,

init_logger(logging.INFO, show_sql=show_sql)

app = lnt.server.ui.app.App.create_standalone(instance_path,)
app = lnt.server.ui.app.App.create_standalone(instance_path)
if debugger:
app.debug = True
if profiler:
Expand Down
62 changes: 10 additions & 52 deletions lnt/server/ui/app.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import importlib.metadata
import io
import logging
import logging.handlers
import sys
import time
import traceback
from logging import Formatter
Expand Down Expand Up @@ -32,10 +30,6 @@
from lnt.util import logger


# The default name of the log file.
LOG_FILENAME = "lnt.log"


class RootSlashPatchMiddleware(object):
def __init__(self, app):
self.app = app
Expand Down Expand Up @@ -190,24 +184,24 @@ def internal_server_error(e):
return app

@staticmethod
def create_standalone(config_path, log_file=None):
def create_standalone(config_path):
"""
Create an instance of a lnt Flask application from a config file.

:param config_path: path to lnt config (directory or config file).

:param log_file: instead of setting up logging, use this log file.
when running in a multiprocess server like gunicorn, you need to use
gunicorn's logging instead (since it is multiprocess safe. In this case
LNT will print to to stderr and it can be collected by gunicorn. The
LNT logs page will show this unified log page.

:return: a LNT Flask App, ready to be loaded into a wsgi server.

"""
instance = lnt.server.instance.Instance.frompath(config_path)
app = App.create_with_instance(instance)
app.start_file_logging(log_file)

# Always log to stderr. In production, the webserver is generally run
# inside a Docker container where logging to stderr is the de facto
# standard.
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
handler.setFormatter(Formatter('%(levelname)s: %(message)s [in %(filename)s:%(lineno)d %(asctime)s]'))
app.logger.addHandler(handler)

return app

def __init__(self, name):
Expand Down Expand Up @@ -241,42 +235,6 @@ def load_config(self, instance):

lnt.server.db.rules_manager.register_hooks()

def start_file_logging(self, log_file_name):
"""Start server production logging. At this point flask already logs
to stderr, so just log to a file as well.

"""
# Always Print to screen.
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(Formatter('%(levelname)s: %(message)s '
'[in %(filename)s:%(lineno)d %(asctime)s]'))
self.logger.addHandler(ch)

# When running in a server config, use the server to setup the log
# file. If there is more than one process running, this will not work
# well.
if not log_file_name:
self.config['log_file_name'] = LOG_FILENAME
try:
rotating = logging.handlers.RotatingFileHandler(
LOG_FILENAME, maxBytes=1048576, backupCount=5)
rotating.setFormatter(Formatter(
'%(asctime)s %(levelname)s: %(message)s '
'[in %(filename)s:%(lineno)d]'
))
rotating.setLevel(logging.DEBUG)
self.logger.addHandler(rotating)
except (OSError, IOError) as e:
print("Error making log file",
LOG_FILENAME, str(e), file=sys.stderr)
print("Will not log to file.", file=sys.stderr)
else:
self.logger.info("Started file logging.")
print("Logging to :", LOG_FILENAME)
else:
self.config['log_file_name'] = log_file_name


def create_jinja_environment(env=None):
"""
Expand Down
1 change: 0 additions & 1 deletion lnt/server/ui/templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,6 @@
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">System<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="{{ url_for('.log') }}">Logs</a></li>
<li><a href="{{ url_for('.rules') }}">Rules</a></li>
<li><a href="{{ url_for('.profile_admin') }}">Profiles</a></li>
<li><a href="{{ url_for('.static', filename='docs/index.html') }}">Documentation</a></li>
Expand Down
18 changes: 0 additions & 18 deletions lnt/server/ui/templates/log.html

This file was deleted.

7 changes: 0 additions & 7 deletions lnt/server/ui/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1797,13 +1797,6 @@ def rules():
return render_template("rules.html", rules=discovered_rules)


@frontend.route('/log')
def log():
with open(current_app.config['log_file_name'], 'r') as f:
log_lines = f.readlines()
return render_template("log.html", log_lines=log_lines)


@frontend.route('/debug')
def debug():
assert not current_app.debug
Expand Down
1 change: 0 additions & 1 deletion tests/server/ui/V4Pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,6 @@ def main():
check_html(client, '/db_default/summary_report')

check_html(client, '/rules')
check_html(client, '/log')
resp = check_code(client, '/__health')
assert resp.get_data(as_text=True) == "Ok"
resp = check_code(client, '/ping')
Expand Down