Skip to content
Open
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
4 changes: 4 additions & 0 deletions jena-fuseki/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ COPY shiro.ini $FUSEKI_HOME/shiro.ini
COPY docker-entrypoint.sh /
RUN chmod 755 /docker-entrypoint.sh

COPY logging.sh $FUSEKI_HOME/logging.sh
RUN chmod 444 $FUSEKI_HOME/logging.sh

COPY log4j2.properties $FUSEKI_HOME/log4j2.properties.templ

COPY load.sh $FUSEKI_HOME/
COPY tdbloader $FUSEKI_HOME/
Expand Down
15 changes: 15 additions & 0 deletions jena-fuseki/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@ heap (default: 1200 MiB), set the `JVM_ARGS` environment with `-e`:

docker run -p 3030:3030 -e JVM_ARGS=-Xmx2g stain/jena-fuseki

## Customize logging

The Docker container outputs logs to stdout which can be read by using docker logs CONTAINER_ID.
The log entries follows the pattern of `09:44:30 INFO Entrypoint :: Initializing Apache Jena Fuseki`.
The first component is the timestamp of the event and it can changed with the LOG_FORMAT variable.

For example if you were to start the container like this:

```docker run -p 3030:3030 -e LOG_FORMAT="%y-%m-%d %H:%M:%S %% %Z" stain/jena-fuseki```

Then you would see log entries like theese:

```24-12-14 09:44:30 % UTC INFO Entrypoint :: Initializing Apache Jena Fuseki```

Please read the man page for date(1) for information about strfttime format.

## Data persistence

Expand Down
50 changes: 38 additions & 12 deletions jena-fuseki/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,54 @@
# See the License for the specific language governing permissions and
# limitations under the License.

source $FUSEKI_HOME/logging.sh
set -e

# Check if $LOG_FORMAT contains any invalid specifiers
# The regex ^((%[aAbBcdHIjmMpSUwWxXyYZFT%])|[^%])+$ matches strings that consist
# of valid strftime format specifiers (% followed by a valid character), any non-% character.
# It ensures the string contains valid format elements, including literals and percent signs.
# Valid examples, please date(1) manpage for information on the valid format:
# LOG_FORMAT="%y%m%d%H%M%S" ## 241214174530
# LOG_FORMAT="%Y-%m-%d %H:%M:%S" ## 2024-12-14 17:45:30
# LOG_FORMAT="%y-%m-%d %H:%M:%S %% %Z" ## 24-12-14 17:45:30 % UTC

if [ ! -z "$LOG_FORMAT" ] && ! echo -n "$LOG_FORMAT" | grep -qE '^((%[aAbBcdHIjmMpSUwWxXyYZFT%])|[^%])+$'; then
invalid_strfttime_format=$LOG_FORMAT
unset LOG_FORMAT
log "WARN" "Invalid strfttime date format specifier in '$invalid_strfttime_format'."
fi

if [ ! -f "$FUSEKI_BASE/shiro.ini" ] ; then
# First time
echo "###################################"
echo "Initializing Apache Jena Fuseki"
echo ""
cp "$FUSEKI_HOME/shiro.ini" "$FUSEKI_BASE/shiro.ini"
log "INFO" "###################################"
log "INFO" "Initializing Apache Jena Fuseki"

cp ${FUSEKI_HOME}/shiro.ini ${FUSEKI_BASE}/shiro.ini

if [ -z "$ADMIN_PASSWORD" ] ; then
ADMIN_PASSWORD=$(pwgen -s 15)
echo "Randomly generated admin password:"
echo ""
echo "admin=$ADMIN_PASSWORD"
log "INFO" "Randomly generated admin password:"
log "INFO" "admin=$ADMIN_PASSWORD"
fi
echo ""
echo "###################################"
log "INFO" "###################################"
fi

if [ -d "/fuseki-extra" ] && [ ! -d "$FUSEKI_BASE/extra" ] ; then
ln -s "/fuseki-extra" "$FUSEKI_BASE/extra"
fi

if [ ! -z "$LOG_FORMAT" ]; then
cp ${FUSEKI_HOME}/log4j2.properties.templ ${FUSEKI_BASE}/log4j2.properties
# translate the format to so it works with Log4j2
LOG4J2_FORMAT="%d{$(translate_to_log4j2_format "$LOG_FORMAT")}"
export LOG4J2_FORMAT
envsubst '${LOG4J2_FORMAT}' < "$FUSEKI_BASE/log4j2.properties" > "$FUSEKI_BASE/log4j2.properties.$$" && \
mv "$FUSEKI_BASE/log4j2.properties.$$" "$FUSEKI_BASE/log4j2.properties"
unset LOG4J2_FORMAT
export LOGGING="-Dlog4j2.configurationFile=$FUSEKI_BASE/log4j2.properties"
fi

# $ADMIN_PASSWORD only modifies if ${ADMIN_PASSWORD}
# is in shiro.ini
if [ -n "$ADMIN_PASSWORD" ] ; then
Expand All @@ -56,7 +82,7 @@ else
fi

# Wait until server is up
echo "Waiting for Fuseki to finish starting up..."
log "INFO" "Waiting for Fuseki to finish starting up..."
until $(curl --output /dev/null --silent --head --fail http://localhost:3030); do
sleep 1s
done
Expand All @@ -65,13 +91,13 @@ done
printenv | egrep "^FUSEKI_DATASET_" | while read env_var
do
dataset=$(echo $env_var | egrep -o "=.*$" | sed 's/^=//g')
echo "Creating dataset $dataset"
log "INFO" "Creating dataset $dataset"
curl -s 'http://localhost:3030/$/datasets'\
-u admin:${ADMIN_PASSWORD}\
-H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8'\
--data "dbName=${dataset}&dbType=${TDB_VERSION}"
done
echo "Fuseki is available :-)"
log "INFO" "Fuseki is available :-)"
unset ADMIN_PASSWORD # Don't keep it in memory

# rejoin our exec
Expand Down
64 changes: 64 additions & 0 deletions jena-fuseki/log4j2.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
## Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
status = error
name = PropertiesConfig
filters = threshold

filter.threshold.type = ThresholdFilter
filter.threshold.level = ALL

appender.console.type = Console
appender.console.name = OUT
appender.console.target = SYSTEM_ERR
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = $LOG4J2_FORMAT %-5p %-15c{1} :: %m%n

rootLogger.level = INFO
rootLogger.appenderRef.stdout.ref = OUT

logger.jena.name = org.apache.jena
logger.jena.level = INFO

logger.arq-exec.name = org.apache.jena.arq.exec
logger.arq-exec.level = INFO

logger.arq-info.name = org.apache.jena.arq.info
logger.arq-info.level = INFO

logger.riot.name = org.apache.jena.riot
logger.riot.level = INFO

logger.fuseki.name = org.apache.jena.fuseki
logger.fuseki.level = INFO

logger.fuseki-fuseki.name = org.apache.jena.fuseki.Fuseki
logger.fuseki-fuseki.level = INFO

logger.fuseki-server.name = org.apache.jena.fuseki.Server
logger.fuseki-server.level = INFO

logger.fuseki-config.name = org.apache.jena.fuseki.Config
logger.fuseki-config.level = INFO

logger.fuseki-admin.name = org.apache.jena.fuseki.Admin
logger.fuseki-admin.level = INFO

logger.jetty.name = org.eclipse.jetty
logger.jetty.level = WARN

logger.shiro.name = org.apache.shiro
logger.shiro.level = WARN

# Hide bug with Shiro 1.5.0+, 2.0.0
logger.shiro-realm.name = org.apache.shiro.realm.text.IniRealm
logger.shiro-realm.level = ERROR

# This goes out in NCSA format
appender.plain.type = Console
appender.plain.name = PLAIN
appender.plain.layout.type = PatternLayout
appender.plain.layout.pattern = %m%n

logger.fuseki-request.name = org.apache.jena.fuseki.Request
logger.fuseki-request.additivity = false
logger.fuseki-request.level = OFF
logger.fuseki-request.appenderRef.plain.ref = PLAIN
39 changes: 39 additions & 0 deletions jena-fuseki/logging.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/sh

log() {
local level="$1"
shift
local message="$*"
local timestamp
if [ -z "$LOG_FORMAT" ]; then
LOG_FORMAT="%H:%M:%S"
fi
timestamp=$(date +"$LOG_FORMAT") # Get current time in HH:MM:SS format, which is used by Fuseki logging
printf "%s %-5s %-15s :: %s\n" "$timestamp" "$level" Entrypoint "$message"
}

translate_to_log4j2_format() {
local strfttime_format="$1"
# Define translation patterns using Bash parameter substitutions
local log4j_format="$strfttime_format"
log4j_format="${log4j_format//%a/EEE}" # Abbreviated weekday name
log4j_format="${log4j_format//%A/EEEE}" # Full weekday name
log4j_format="${log4j_format//%b/MMM}" # Abbreviated month name
log4j_format="${log4j_format//%B/MMMM}" # Full month name
log4j_format="${log4j_format//%d/dd}" # Day of the month
log4j_format="${log4j_format//%H/HH}" # Hour (00-23)
log4j_format="${log4j_format//%I/hh}" # Hour (01-12)
log4j_format="${log4j_format//%j/DDD}" # Day of the year
log4j_format="${log4j_format//%m/MM}" # Month
log4j_format="${log4j_format//%M/mm}" # Minute
log4j_format="${log4j_format//%p/a}" # AM or PM
log4j_format="${log4j_format//%S/ss}" # Second
log4j_format="${log4j_format//%y/yy}" # Year (last two digits)
log4j_format="${log4j_format//%Y/yyyy}" # Full year
log4j_format="${log4j_format//%Z/z}" # Time zone
log4j_format="${log4j_format//%F/yyyy-MM-dd}" # Full date
log4j_format="${log4j_format//%T/HH:mm:ss}" # Full time
log4j_format="${log4j_format//%%/%}" # A escaped %

echo $log4j_format
}