Skip to content

Commit

Permalink
refactor runtime log handling, add -l option to boot script to tail c…
Browse files Browse the repository at this point in the history
…ustom log files into stderr
  • Loading branch information
dzuelke committed Aug 20, 2014
1 parent 7247160 commit d1ed071
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 20 deletions.
40 changes: 35 additions & 5 deletions bin/heroku-hhvm-apache2
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
set -o pipefail
# fail harder
set -eu
# for patterns further down
# for ${DOCUMENT_ROOT%%*(/)} pattern further down
shopt -s extglob
# for detecting when -l 'logs/*.log' matches nothing
shopt -s nullglob

php_passthrough() {
local dir=$(dirname "$1")
Expand All @@ -30,6 +32,10 @@ check_exists() {
fi
}

touch_log() {
mkdir -p $(dirname "$1") && touch "$1"
}

print_help() {
echo "\
Boots HHVM together with Apache2 on Heroku and for local development.
Expand All @@ -55,12 +61,18 @@ Options:
-h Display this help screen and exit.
-i <php.ini> The path to the php.ini file to use.
[default: $COMPOSER_VENDOR_DIR/heroku/heroku-buildpack-php/conf/hhvm/php.ini]
-l <tailme.log> Path to additional log file to tail to STDERR so its
contents appear in 'heroku logs'. If the file does not
exist, it will be created. Wildcards are allowed, but
must be quoted and must match already existing files.
Note: this option can be repeated multiple times.
All file paths must be relative to '$HEROKU_APP_DIR'.
Any file name that ends in '.php' will be run through the PHP interpreter first.
You may use this for templating although this is less useful than e.g. for Nginx
where unlike in Apache2, you cannot reference environment variables in config
files using a '\${VARNAME}' syntax.
All file paths must be relative to '$HEROKU_APP_DIR'.
If you would like to use the -C and -c options together, make sure you retain
the appropriate include mechanisms (see default configs for details).
Expand All @@ -75,7 +87,10 @@ export PORT=${PORT:-$(( $RANDOM+1024 ))}
export COMPOSER_VENDOR_DIR=$(composer config vendor-dir 2> /dev/null | tail -n 1) # tail, as composer echos outdated version warnings to STDOUT
export COMPOSER_BIN_DIR=$(composer config bin-dir 2> /dev/null | tail -n 1) # tail, as composer echos outdated version warnings to STDOUT

while getopts ":C:c:i:h" opt; do
# our standard logs
logs=( "/tmp/heroku.apache2_error.$PORT.log" "/tmp/heroku.apache2_access.$PORT.log" )

while getopts ":C:c:i:l:h" opt; do
case $opt in
C)
httpd_config_include=$(check_exists "$OPTARG" "C")
Expand All @@ -86,6 +101,21 @@ while getopts ":C:c:i:h" opt; do
i)
php_config=$(check_exists "$OPTARG" "i")
;;
l)
logarg=( $OPTARG ) # must not quote this or wildcards won't get expanded into individual values
if [[ ${#logarg[@]} -eq 0 ]]; then # we set nullglob to detect if a pattern matched nothing (then the array is empty)
echo "Pattern '$OPTARG' passed to option -l matched no files" >&2
exit 1
fi
for logfile in "${logarg[@]}"; do
if [[ -d "$logfile" ]]; then
echo "-l '$logfile': is a directory" >&2
exit 1
fi
touch_log "$logfile" || { echo "Could not touch '$logfile'; permissions problem?" >&2; exit 1; }
logs+=("$logfile") # must quote here in case a wildcard matched a file with a space in the name
done
;;
h)
print_help 2>&1
exit
Expand Down Expand Up @@ -120,7 +150,7 @@ if [[ "$#" == "1" ]]; then
exit 1
else
# strip trailing slashes if present
DOCUMENT_ROOT=${DOCUMENT_ROOT%%*(/)}
DOCUMENT_ROOT=${DOCUMENT_ROOT%%*(/)} # powered by extglob
echo "DOCUMENT_ROOT changed to '$DOCUMENT_ROOT'" >&2
fi
fi
Expand Down Expand Up @@ -157,7 +187,7 @@ trap 'trap - EXIT; echo "Going down, terminating child processes..." >&2; jobs -

# redirect logs to STDERR; write "tail ..." to the shared pipe if it exits
echo "Starting log redirection..." >&2
( touch "/tmp/heroku.apache2_error.$PORT.log" "/tmp/heroku.apache2_access.$PORT.log"; tail -qF -n 0 /tmp/heroku.*.$PORT.log 1>&2 || true; echo "tail heroku.*.$PORT.log" >&3; ) 3> $wait_pipe &
( touch "${logs[@]}"; tail -qF -n 0 "${logs[@]}" 1>&2 || true; echo 'tail "${logs[@]}"' >&3; ) 3> $wait_pipe &
# start HHVM; write "hhvm" to the shared pipe if it exits
echo "Starting hhvm..." >&2
( hhvm --mode server -vServer.Type=fastcgi -vServer.FileSocket=/tmp/heroku.fcgi.$PORT.sock -c "$php_config" || true; echo "hhvm" >&3; ) 3> $wait_pipe &
Expand Down
40 changes: 35 additions & 5 deletions bin/heroku-hhvm-nginx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
set -o pipefail
# fail harder
set -eu
# for patterns further down
# for ${DOCUMENT_ROOT%%*(/)} pattern further down
shopt -s extglob
# for detecting when -l 'logs/*.log' matches nothing
shopt -s nullglob

php_passthrough() {
local dir=$(dirname "$1")
Expand All @@ -30,6 +32,10 @@ check_exists() {
fi
}

touch_log() {
mkdir -p $(dirname "$1") && touch "$1"
}

print_help() {
echo "\
Boots HHVM together with Nginx on Heroku and for local development.
Expand Down Expand Up @@ -57,11 +63,17 @@ Options:
-h Display this help screen and exit.
-i <php.ini> The path to the php.ini file to use.
[default: $COMPOSER_VENDOR_DIR/heroku/heroku-buildpack-php/conf/hhvm/php.ini]
-l <tailme.log> Path to additional log file to tail to STDERR so its
contents appear in 'heroku logs'. If the file does not
exist, it will be created. Wildcards are allowed, but
must be quoted and must match already existing files.
Note: this option can be repeated multiple times.
All file paths must be relative to '$HEROKU_APP_DIR'.
Any file name that ends in '.php' will be run through the PHP interpreter first.
You may use this for templating; this is, for instance, necessary for Nginx,
where environment variables cannot be referenced in configuration files.
All file paths must be relative to '$HEROKU_APP_DIR'.
If you would like to use the -C and -c options together, make sure you retain
the appropriate include mechanisms (see default configs for details).
Expand All @@ -76,7 +88,10 @@ export PORT=${PORT:-$(( $RANDOM+1024 ))}
export COMPOSER_VENDOR_DIR=$(composer config vendor-dir 2> /dev/null | tail -n 1) # tail, as composer echos outdated version warnings to STDOUT
export COMPOSER_BIN_DIR=$(composer config bin-dir 2> /dev/null | tail -n 1) # tail, as composer echos outdated version warnings to STDOUT

while getopts ":C:c:i:h" opt; do
# our standard logs
logs=( "/tmp/heroku.nginx_access.$PORT.log" )

while getopts ":C:c:i:l:h" opt; do
case $opt in
C)
nginx_config_include=$(check_exists "$OPTARG" "C")
Expand All @@ -87,6 +102,21 @@ while getopts ":C:c:i:h" opt; do
i)
php_config=$(check_exists "$OPTARG" "i")
;;
l)
logarg=( $OPTARG ) # must not quote this or wildcards won't get expanded into individual values
if [[ ${#logarg[@]} -eq 0 ]]; then # we set nullglob to detect if a pattern matched nothing (then the array is empty)
echo "Pattern '$OPTARG' passed to option -l matched no files" >&2
exit 1
fi
for logfile in "${logarg[@]}"; do
if [[ -d "$logfile" ]]; then
echo "-l '$logfile': is a directory" >&2
exit 1
fi
touch_log "$logfile" || { echo "Could not touch '$logfile'; permissions problem?" >&2; exit 1; }
logs+=("$logfile") # must quote here in case a wildcard matched a file with a space in the name
done
;;
h)
print_help 2>&1
exit
Expand Down Expand Up @@ -120,7 +150,7 @@ if [[ "$#" == "1" ]]; then
exit 1
else
# strip trailing slashes if present
DOCUMENT_ROOT=${DOCUMENT_ROOT%%*(/)}
DOCUMENT_ROOT=${DOCUMENT_ROOT%%*(/)} # powered by extglob
echo "DOCUMENT_ROOT changed to '$DOCUMENT_ROOT'" >&2
fi
fi
Expand Down Expand Up @@ -157,7 +187,7 @@ trap 'trap - EXIT; echo "Going down, terminating child processes..." >&2; jobs -

# redirect logs to STDERR; write "tail ..." to the shared pipe if it exits
echo "Starting log redirection..." >&2
( touch "/tmp/heroku.nginx_access.$PORT.log"; tail -qF -n 0 /tmp/heroku.*.$PORT.log 1>&2 || true; echo "tail heroku.*.$PORT.log" >&3; ) 3> $wait_pipe &
( touch "${logs[@]}"; tail -qF -n 0 "${logs[@]}" 1>&2 || true; echo 'tail "${logs[@]}"' >&3; ) 3> $wait_pipe &
# start HHVM; write "hhvm" to the shared pipe if it exits
echo "Starting hhvm..." >&2
( hhvm --mode server -vServer.Type=fastcgi -vServer.FileSocket=/tmp/heroku.fcgi.$PORT.sock -c "$php_config" || true; echo "hhvm" >&3; ) 3> $wait_pipe &
Expand Down
40 changes: 35 additions & 5 deletions bin/heroku-php-apache2
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
set -o pipefail
# fail harder
set -eu
# for patterns further down
# for ${DOCUMENT_ROOT%%*(/)} pattern further down
shopt -s extglob
# for detecting when -l 'logs/*.log' matches nothing
shopt -s nullglob

php_passthrough() {
local dir=$(dirname "$1")
Expand All @@ -30,6 +32,10 @@ check_exists() {
fi
}

touch_log() {
mkdir -p $(dirname "$1") && touch "$1"
}

print_help() {
echo "\
Boots PHP-FPM together with Apache2 on Heroku and for local development.
Expand Down Expand Up @@ -62,12 +68,18 @@ Options:
-h Display this help screen and exit.
-i <php.ini> The path to the php.ini file to use.
[default: $COMPOSER_VENDOR_DIR/heroku/heroku-buildpack-php/conf/php/php.ini]
-l <tailme.log> Path to additional log file to tail to STDERR so its
contents appear in 'heroku logs'. If the file does not
exist, it will be created. Wildcards are allowed, but
must be quoted and must match already existing files.
Note: this option can be repeated multiple times.
All file paths must be relative to '$HEROKU_APP_DIR'.
Any file name that ends in '.php' will be run through the PHP interpreter first.
You may use this for templating although this is less useful than e.g. for Nginx
where unlike in Apache2, you cannot reference environment variables in config
files using a '\${VARNAME}' syntax.
All file paths must be relative to '$HEROKU_APP_DIR'.
If you would like to use the -C and -c or -F and -f options together, make sure
you retain the appropriate include mechanisms (see default configs for details).
Expand All @@ -82,7 +94,10 @@ export PORT=${PORT:-$(( $RANDOM+1024 ))}
export COMPOSER_VENDOR_DIR=$(composer config vendor-dir 2> /dev/null | tail -n 1) # tail, as composer echos outdated version warnings to STDOUT
export COMPOSER_BIN_DIR=$(composer config bin-dir 2> /dev/null | tail -n 1) # tail, as composer echos outdated version warnings to STDOUT

while getopts ":C:c:F:f:i:h" opt; do
# our standard logs
logs=( "/tmp/heroku.php-fpm.$PORT.log" "/tmp/heroku.apache2_error.$PORT.log" "/tmp/heroku.apache2_access.$PORT.log" )

while getopts ":C:c:F:f:i:l:h" opt; do
case $opt in
C)
httpd_config_include=$(check_exists "$OPTARG" "C")
Expand All @@ -99,6 +114,21 @@ while getopts ":C:c:F:f:i:h" opt; do
i)
php_config=$(check_exists "$OPTARG" "i")
;;
l)
logarg=( $OPTARG ) # must not quote this or wildcards won't get expanded into individual values
if [[ ${#logarg[@]} -eq 0 ]]; then # we set nullglob to detect if a pattern matched nothing (then the array is empty)
echo "Pattern '$OPTARG' passed to option -l matched no files" >&2
exit 1
fi
for logfile in "${logarg[@]}"; do
if [[ -d "$logfile" ]]; then
echo "-l '$logfile': is a directory" >&2
exit 1
fi
touch_log "$logfile" || { echo "Could not touch '$logfile'; permissions problem?" >&2; exit 1; }
logs+=("$logfile") # must quote here in case a wildcard matched a file with a space in the name
done
;;
h)
print_help 2>&1
exit
Expand Down Expand Up @@ -134,7 +164,7 @@ if [[ "$#" == "1" ]]; then
exit 1
else
# strip trailing slashes if present
DOCUMENT_ROOT=${DOCUMENT_ROOT%%*(/)}
DOCUMENT_ROOT=${DOCUMENT_ROOT%%*(/)} # powered by extglob
echo "DOCUMENT_ROOT changed to '$DOCUMENT_ROOT'" >&2
fi
fi
Expand Down Expand Up @@ -182,7 +212,7 @@ trap 'trap - EXIT; echo "Going down, terminating child processes..." >&2; jobs -

# redirect logs to STDERR; write "tail ..." to the shared pipe if it exits
echo "Starting log redirection..." >&2
( touch "/tmp/heroku.php-fpm.$PORT.log" "/tmp/heroku.apache2_error.$PORT.log" "/tmp/heroku.apache2_access.$PORT.log"; tail -qF -n 0 /tmp/heroku.*.$PORT.log 1>&2 || true; echo "tail heroku.*.$PORT.log" >&3; ) 3> $wait_pipe &
( touch "${logs[@]}"; tail -qF -n 0 "${logs[@]}" 1>&2 || true; echo 'tail "${logs[@]}"' >&3; ) 3> $wait_pipe &
# start FPM; write "php-fpm" to the shared pipe if it exits
echo "Starting php-fpm..." >&2
( php-fpm --nodaemonize -y "$fpm_config" -c "$php_config" || true; echo "php-fpm" >&3; ) 3> $wait_pipe &
Expand Down
40 changes: 35 additions & 5 deletions bin/heroku-php-nginx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
set -o pipefail
# fail harder
set -eu
# for patterns further down
# for ${DOCUMENT_ROOT%%*(/)} pattern further down
shopt -s extglob
# for detecting when -l 'logs/*.log' matches nothing
shopt -s nullglob

php_passthrough() {
local dir=$(dirname "$1")
Expand All @@ -30,6 +32,10 @@ check_exists() {
fi
}

touch_log() {
mkdir -p $(dirname "$1") && touch "$1"
}

print_help() {
echo "\
Boots PHP-FPM together with Nginx on Heroku and for local development.
Expand Down Expand Up @@ -64,11 +70,17 @@ Options:
-h Display this help screen and exit.
-i <php.ini> The path to the php.ini file to use.
[default: $COMPOSER_VENDOR_DIR/heroku/heroku-buildpack-php/conf/php/php.ini]
-l <tailme.log> Path to additional log file to tail to STDERR so its
contents appear in 'heroku logs'. If the file does not
exist, it will be created. Wildcards are allowed, but
must be quoted and must match already existing files.
Note: this option can be repeated multiple times.
All file paths must be relative to '$HEROKU_APP_DIR'.
Any file name that ends in '.php' will be run through the PHP interpreter first.
You may use this for templating; this is, for instance, necessary for Nginx,
where environment variables cannot be referenced in configuration files.
All file paths must be relative to '$HEROKU_APP_DIR'.
If you would like to use the -C and -c or -F and -f options together, make sure
you retain the appropriate include mechanisms (see default configs for details).
Expand All @@ -83,7 +95,10 @@ export PORT=${PORT:-$(( $RANDOM+1024 ))}
export COMPOSER_VENDOR_DIR=$(composer config vendor-dir 2> /dev/null | tail -n 1) # tail, as composer echos outdated version warnings to STDOUT
export COMPOSER_BIN_DIR=$(composer config bin-dir 2> /dev/null | tail -n 1) # tail, as composer echos outdated version warnings to STDOUT

while getopts ":C:c:F:f:i:h" opt; do
# our standard logs
logs=( "/tmp/heroku.php-fpm.$PORT.log" "/tmp/heroku.nginx_access.$PORT.log" )

while getopts ":C:c:F:f:i:l:h" opt; do
case $opt in
C)
nginx_config_include=$(check_exists "$OPTARG" "C")
Expand All @@ -100,6 +115,21 @@ while getopts ":C:c:F:f:i:h" opt; do
i)
php_config=$(check_exists "$OPTARG" "i")
;;
l)
logarg=( $OPTARG ) # must not quote this or wildcards won't get expanded into individual values
if [[ ${#logarg[@]} -eq 0 ]]; then # we set nullglob to detect if a pattern matched nothing (then the array is empty)
echo "Pattern '$OPTARG' passed to option -l matched no files" >&2
exit 1
fi
for logfile in "${logarg[@]}"; do
if [[ -d "$logfile" ]]; then
echo "-l '$logfile': is a directory" >&2
exit 1
fi
touch_log "$logfile" || { echo "Could not touch '$logfile'; permissions problem?" >&2; exit 1; }
logs+=("$logfile") # must quote here in case a wildcard matched a file with a space in the name
done
;;
h)
print_help 2>&1
exit
Expand Down Expand Up @@ -134,7 +164,7 @@ if [[ "$#" == "1" ]]; then
exit 1
else
# strip trailing slashes if present
DOCUMENT_ROOT=${DOCUMENT_ROOT%%*(/)}
DOCUMENT_ROOT=${DOCUMENT_ROOT%%*(/)} # powered by extglob
echo "DOCUMENT_ROOT changed to '$DOCUMENT_ROOT'" >&2
fi
fi
Expand Down Expand Up @@ -182,7 +212,7 @@ trap 'trap - EXIT; echo "Going down, terminating child processes..." >&2; jobs -

# redirect logs to STDERR; write "tail ..." to the shared pipe if it exits
echo "Starting log redirection..." >&2
( touch "/tmp/heroku.php-fpm.$PORT.log" "/tmp/heroku.nginx_access.$PORT.log"; tail -qF -n 0 /tmp/heroku.*.$PORT.log 1>&2 || true; echo "tail heroku.*.$PORT.log" >&3; ) 3> $wait_pipe &
( touch "${logs[@]}"; tail -qF -n 0 "${logs[@]}" 1>&2 || true; echo 'tail "${logs[@]}"' >&3; ) 3> $wait_pipe &
# start FPM; write "php-fpm" to the shared pipe if it exits
echo "Starting php-fpm..." >&2
( php-fpm --nodaemonize -y "$fpm_config" -c "$php_config" || true; echo "php-fpm" >&3; ) 3> $wait_pipe &
Expand Down

0 comments on commit d1ed071

Please sign in to comment.