summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAssaf Gordon <assafgordon@gmail.com>2016-02-26 16:20:04 (GMT)
committerAssaf Gordon <assafgordon@gmail.com>2016-02-26 16:20:04 (GMT)
commitd029a1d4aaba4c9e2b023a5011e608b53a99a4ee (patch)
tree29c709195613fb29e95e77f3e45405da0451d986
parent2193040c363f989ca6f70f1d3ef4c6089a3ab237 (diff)
downloadcode-snippets-d029a1d4aaba4c9e2b023a5011e608b53a99a4ee.zip
code-snippets-d029a1d4aaba4c9e2b023a5011e608b53a99a4ee.tar.gz
code-snippets-d029a1d4aaba4c9e2b023a5011e608b53a99a4ee.tar.bz2
log-file-file{1,2}.sh: example of saving stdout/err into logs
-rwxr-xr-xlog-to-file1.sh71
-rwxr-xr-xlog-to-file2.sh90
-rw-r--r--metadata.yml4
3 files changed, 165 insertions, 0 deletions
diff --git a/log-to-file1.sh b/log-to-file1.sh
new file mode 100755
index 0000000..c2f4b4b
--- /dev/null
+++ b/log-to-file1.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+# Example of duplicating STDOUT+STDERR into a log file
+# Copyright (C) 2016 Assaf Gordon <assafgordon@gmail.com>
+# License: MIT
+#
+# This script demonstate how to setup logging of all STDOUT and STDERR
+# outputs into a log file (in addition to also outputing it to the
+# original STDOUT/STDERR (e.g. the terminal).
+#
+# The function 'setup_logging1' MERGES stdout and stderr into one log file.
+# This makes it easier to review later, but loses the distinction between
+# what was printed to STDOUT and what was printed to STDERR.
+# depending on your application, this might be acceptable.
+#
+# See 'log-to-file2.sh' for an alternative (saving STDOUT and STDERR into
+# two separate files).
+
+die()
+{
+ BASE=$(basename "$0")
+ echo "$BASE: error: $@" >&2
+ exit 1
+}
+
+setup_logging1()
+{
+ logfile="$1"
+ test -z "$logfile" \
+ && die "internal error: missing log filename parameter"
+
+ # Create a tmp directory, to store the fifo
+ __pipedir=$(mktemp -d -t log.XXXXXX) \
+ || die "failed to create tmp directory"
+
+ # Create the fifo file
+ mkfifo "${__pipedir}/log-fifo" \
+ || die "failed to create fifo"
+
+ # Run 'tee' in the background, duplicating
+ # the input (from the fifo) to both STDOUT and the log file
+ tee "$logfile" < "${__pipedir}/log-fifo" &
+
+ # Re-exec this shell instance, merging STDERR into STDOUT
+ # and redirecting STDOUT into the fifo
+ exec >"${__pipedir}/log-fifo" 2>&1
+
+ # Delete the FIFO and the temp dir -
+ # no harm since the the fifo's file-descriptior is
+ # held open by 'tee'. Saves the trouble of cleanup on exit.
+ rm "${__pipedir}/log-fifo" \
+ || die "failed to cleanup fifo file"
+ rmdir "${__pipedir}" \
+ || die "failed to cleanup tmp dir"
+}
+
+
+# Setup logging into a file with a time stamp
+log=program-$(date +%F-%H%M%S).log
+setup_logging1 "$log"
+
+# Simulate some output both to STDOUT and STDERR
+echo "Logging Example - anything you see printed to the terminal"
+echo " is also saved in the file '$log'"
+
+echo "Hello (Stdout)"
+echo "Hello (stderr)" >&2
+
+# Simulate potential error messages to stderr
+echo "Trying to copy non-existing file (which will fail):"
+cp "/foo/bar" "/bar/baz"
diff --git a/log-to-file2.sh b/log-to-file2.sh
new file mode 100755
index 0000000..2b65dcf
--- /dev/null
+++ b/log-to-file2.sh
@@ -0,0 +1,90 @@
+#!/bin/sh
+
+# Example of duplicating STDOUT+STDERR into a log file
+# Copyright (C) 2016 Assaf Gordon <assafgordon@gmail.com>
+# License: MIT
+#
+# This script demonstate how to setup logging of all STDOUT and STDERR
+# outputs into log files (in addition to also outputing it to the
+# original STDOUT/STDERR (e.g. the terminal).
+#
+# The function 'setup_logging2' creates two separate log files, one for
+# stderr and one for stdout. This makes it easy to detect errors
+# (if there's lots of non-error noise on STDOUT), but it might make it
+# hard to know when/where the error was printed during the program's life time.
+#
+# NOTE:
+# when STDERR and STDOUT are different streams, STDERR is usually not buffered
+# and printed quickly, while STDOUT is buffered and printed slowly, thus the
+# order of the messages might seem 'incorrect'.
+#
+# See 'log-to-file1.sh' for an alternative (saving STDOUT and STDERR
+# into one merged file).
+#
+
+die()
+{
+ BASE=$(basename "$0")
+ echo "$BASE: error: $@" >&2
+ exit 1
+}
+
+setup_logging2()
+{
+ logprefix="$1"
+ test -z "$logprefix" \
+ && die "internal error: missing log filename parameter"
+
+ # Create a tmp directory, to store the fifo
+ __pipedir=$(mktemp -d -t log.XXXXXX) \
+ || die "failed to create tmp directory"
+
+ # Create the fifo file
+ mkfifo "${__pipedir}/log-fifo-out" \
+ || die "failed to create fifo"
+ mkfifo "${__pipedir}/log-fifo-err" \
+ || die "failed to create fifo"
+
+ # Run 'tee' in the background, duplicating
+ # the input (from the fifo) to both STDOUT and the log file
+ tee "${logprefix}.stdout.log" < "${__pipedir}/log-fifo-out" &
+
+ # duplicate the input to both file and STDERR
+ tee "${logprefix}.stderr.log" < "${__pipedir}/log-fifo-err" >&2 &
+
+ # Re-exec this shell instance, merging STDERR into STDOUT
+ # and redirecting STDOUT into the fifo
+ exec >"${__pipedir}/log-fifo-out" 2>"${__pipedir}/log-fifo-err"
+
+ # Delete the FIFO and the temp dir -
+ # no harm since the the fifo's file-descriptior is
+ # held open by 'tee'. Saves the trouble of cleanup on exit.
+ rm "${__pipedir}/log-fifo-out" "${__pipedir}/log-fifo-err"\
+ || die "failed to cleanup fifo files"
+ rmdir "${__pipedir}" \
+ || die "failed to cleanup tmp dir"
+}
+
+
+# Setup logging into a file with a time stamp
+log=program-$(date +%F-%H%M%S)
+setup_logging2 "$log"
+
+# Simulate some output both to STDOUT and STDERR
+echo "Logging Example - anything you see printed to the terminal"
+echo " is also saved in log files:"
+echo " stdout: $log.stdout.log"
+echo " stderr: $log.stderr.log"
+
+echo "Hello (Stdout)"
+echo "Hello (stderr)" >&2
+
+# Simulate potential error messages to stdout/err.
+# NOTE:
+# stdout (the 'echo') will be saved in one file,
+# while the error (from 'cp') will be saved in another.
+# this makes it easy to spot errors, but might make it harder
+# to understand the context (unless progress messages are also printed
+# to STDERR).
+echo "Trying to copy non-existing file (which will fail):"
+cp "/foo/bar" "/bar/baz"
diff --git a/metadata.yml b/metadata.yml
index 87d6d96..b6eda2d 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -5,6 +5,10 @@ files:
description: 'Python script skeleton with argparse and help screen'
git-post-update-jekyll-hook:
description: 'Rebuild a jekyll static website on git-push (similar to github pages)'
+ log-to-file1.sh:
+ description: 'automatically duplicate stdout/err, save into a log file'
+ log-to-file2.sh:
+ description: 'automatically duplicate stdout/err, save into separate log files'
links:
- name: posix-libc-examples
url: https://git.housegordon.org/gitweb/posix-libc-examples.git