2020-06-02 14:20:23 +01:00
|
|
|
#! /usr/bin/env bash
|
|
|
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
#### Detect Toolkit Project Root ####
|
|
|
|
# if realpath is not available, create a semi-equivalent function
|
|
|
|
command -v realpath >/dev/null 2>&1 || realpath() {
|
|
|
|
[[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
|
|
|
|
}
|
|
|
|
SCRIPT_PATH="$(realpath "${BASH_SOURCE[0]}")"
|
|
|
|
SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"
|
|
|
|
TOOLKIT_ROOT="$(realpath "$SCRIPT_DIR/..")"
|
|
|
|
if [[ ! -d "$TOOLKIT_ROOT/bin" ]] || [[ ! -d "$TOOLKIT_ROOT/config" ]]; then
|
|
|
|
echo "ERROR: could not find root of overleaf-toolkit project (inferred project root as '$TOOLKIT_ROOT')"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2023-05-12 07:47:16 -04:00
|
|
|
DEFAULT_TAIL_LINES=20
|
|
|
|
ALL_SERVICES=(chat clsi contacts docstore document-updater filestore git-bridge \
|
2023-10-24 12:28:14 +01:00
|
|
|
mongo notifications real-time redis spelling tags track-changes web \
|
|
|
|
history-v1 project-history)
|
2020-06-02 14:20:23 +01:00
|
|
|
|
2023-05-19 16:29:56 -04:00
|
|
|
LOGS_PID_FILE="/tmp/toolkit-logs.$$.pid"
|
|
|
|
|
2020-06-02 14:20:23 +01:00
|
|
|
function usage() {
|
2023-05-12 07:47:16 -04:00
|
|
|
echo "Usage: bin/logs [OPTIONS] [SERVICES...]
|
|
|
|
|
|
|
|
Services: chat, clsi, contacts, docstore, document-updater, filestore,
|
|
|
|
git-bridge, mongo, notifications, real-time, redis, spelling,
|
2023-10-24 12:28:14 +01:00
|
|
|
tags, track-changes, web, history-v1, project-history
|
2023-05-12 07:47:16 -04:00
|
|
|
|
|
|
|
Options:
|
|
|
|
-f follow log output
|
|
|
|
-n {number} number of lines to print (default $DEFAULT_TAIL_LINES)
|
|
|
|
use '-n all' to show all log lines
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
|
|
|
bin/logs -n 50 web clsi
|
|
|
|
|
|
|
|
bin/logs -n all web > web.log
|
|
|
|
|
|
|
|
bin/logs -f web
|
|
|
|
|
|
|
|
bin/logs -f web chat docstore
|
|
|
|
|
|
|
|
bin/logs -n 100 -f filestore
|
|
|
|
|
|
|
|
bin/logs -f"
|
2020-06-02 14:20:23 +01:00
|
|
|
}
|
|
|
|
|
2023-05-12 07:47:16 -04:00
|
|
|
function parse_args() {
|
|
|
|
TAIL_LINES=$DEFAULT_TAIL_LINES
|
|
|
|
FOLLOW=false
|
|
|
|
|
|
|
|
if [[ $# -gt 0 && $1 =~ ^help|-h|--help$ ]]; then
|
|
|
|
usage && exit
|
|
|
|
fi
|
2020-06-02 14:20:23 +01:00
|
|
|
|
|
|
|
while getopts "fn:" opt
|
|
|
|
do
|
|
|
|
case $opt in
|
2023-05-12 07:47:16 -04:00
|
|
|
f) FOLLOW=true ;;
|
|
|
|
n) TAIL_LINES="$OPTARG" ;;
|
|
|
|
\?) usage && exit 1;;
|
2020-06-02 14:20:23 +01:00
|
|
|
esac
|
|
|
|
done
|
2023-05-12 07:47:16 -04:00
|
|
|
shift $(( OPTIND - 1 ))
|
2020-06-02 14:20:23 +01:00
|
|
|
|
2023-05-12 07:47:16 -04:00
|
|
|
if [[ $# -eq 0 ]]; then
|
|
|
|
SERVICES=("${ALL_SERVICES[@]}")
|
|
|
|
else
|
|
|
|
SERVICES=("$@")
|
2020-06-02 14:20:23 +01:00
|
|
|
fi
|
2023-05-12 07:47:16 -04:00
|
|
|
}
|
2020-06-02 14:20:23 +01:00
|
|
|
|
2023-05-12 07:47:16 -04:00
|
|
|
function docker_compose() {
|
|
|
|
# Ignore stderr and errors when calling docker compose
|
|
|
|
"$TOOLKIT_ROOT/bin/docker-compose" "$@" 2>/dev/null || true
|
|
|
|
}
|
|
|
|
|
2023-05-19 16:29:56 -04:00
|
|
|
function kill_background_jobs() {
|
|
|
|
if [[ ${#COMPOSE_LOGS_PIDS[@]} -gt 0 ]]; then
|
|
|
|
# Kill "docker compose logs" processes
|
|
|
|
kill "${COMPOSE_LOGS_PIDS[@]}" 2>/dev/null || true
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Kill "tail -f" processes started inside the sharelatex container
|
|
|
|
docker_compose exec -T sharelatex bash -c "
|
|
|
|
[[ -f $LOGS_PID_FILE ]] && kill \$(cat $LOGS_PID_FILE) 2>/dev/null
|
|
|
|
rm -f $LOGS_PID_FILE"
|
|
|
|
}
|
|
|
|
|
2023-05-12 07:47:16 -04:00
|
|
|
function show_logs() {
|
2023-05-19 16:29:56 -04:00
|
|
|
COMPOSE_LOGS_PIDS=()
|
|
|
|
trap kill_background_jobs EXIT
|
2023-05-12 07:47:16 -04:00
|
|
|
|
|
|
|
for service in "${SERVICES[@]}"; do
|
|
|
|
if [[ $service =~ ^(git-bridge|mongo|redis)$ ]]; then
|
|
|
|
show_compose_logs "$service" &
|
2023-05-19 16:29:56 -04:00
|
|
|
COMPOSE_LOGS_PIDS+=($!)
|
2023-05-12 07:47:16 -04:00
|
|
|
else
|
|
|
|
show_sharelatex_logs "$service" &
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
wait
|
|
|
|
}
|
|
|
|
|
|
|
|
function show_compose_logs() {
|
|
|
|
local service="$1"
|
|
|
|
local flags=(--no-color)
|
2020-06-02 14:20:23 +01:00
|
|
|
|
2023-05-12 07:47:16 -04:00
|
|
|
if [[ $FOLLOW == "true" ]]; then
|
|
|
|
flags+=(-f)
|
|
|
|
fi
|
|
|
|
if [[ $TAIL_LINES != "all" ]]; then
|
|
|
|
flags+=(--tail="$TAIL_LINES")
|
|
|
|
fi
|
|
|
|
if [[ ${#SERVICES[@]} -eq 1 ]]; then
|
|
|
|
# Do not add a service prefix when outputting logs from a single
|
|
|
|
# service
|
|
|
|
flags+=(--no-log-prefix)
|
|
|
|
fi
|
2020-06-02 14:20:23 +01:00
|
|
|
|
2023-05-12 07:47:16 -04:00
|
|
|
docker_compose logs "${flags[@]}" "$service"
|
|
|
|
}
|
2020-06-02 14:20:23 +01:00
|
|
|
|
2023-05-12 07:47:16 -04:00
|
|
|
function show_sharelatex_logs() {
|
|
|
|
local service="$1"
|
|
|
|
local log_path="/var/log/sharelatex/$service.log"
|
|
|
|
local flags=()
|
|
|
|
|
|
|
|
if [[ $FOLLOW == "true" ]]; then
|
|
|
|
flags+=(-f)
|
|
|
|
fi
|
|
|
|
if [[ $TAIL_LINES = "all" ]]; then
|
|
|
|
flags+=(-n "+1")
|
|
|
|
else
|
|
|
|
flags+=(-n "$TAIL_LINES")
|
2020-06-02 14:20:23 +01:00
|
|
|
fi
|
|
|
|
|
2023-05-19 16:29:56 -04:00
|
|
|
local logs_cmd="[[ -f $log_path ]] && echo \$\$ >> $LOGS_PID_FILE && tail --pid=\$\$ ${flags[*]} $log_path"
|
2023-05-12 07:47:16 -04:00
|
|
|
if [[ ${#SERVICES[@]} -gt 1 ]]; then
|
|
|
|
# Roughly reproduce the service prefix format from docker compose
|
|
|
|
local padded_service
|
|
|
|
padded_service=$(printf "%-13s" "$service")
|
|
|
|
logs_cmd="$logs_cmd | sed -u -e 's/^/$padded_service | /'"
|
|
|
|
fi
|
2020-06-02 14:20:23 +01:00
|
|
|
|
2023-05-12 07:47:16 -04:00
|
|
|
docker_compose exec -T sharelatex bash -c "$logs_cmd"
|
2020-06-02 14:20:23 +01:00
|
|
|
}
|
|
|
|
|
2023-05-12 07:47:16 -04:00
|
|
|
parse_args "$@"
|
|
|
|
show_logs
|