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
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aws/ml-container-creator",
"version": "0.6.1",
"version": "0.7.1",
"description": "Generator for SageMaker AI BYOC paradigm for predictive inference use-cases.",
"type": "module",
"main": "src/app.js",
Expand Down
2 changes: 2 additions & 0 deletions templates/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ RUN chmod +x /usr/bin/serve_trtllm

# Copy startup script
COPY code/cuda_compat.sh /usr/bin/cuda_compat.sh
COPY code/cw_log_forwarder.py /usr/bin/cw_log_forwarder.py
COPY code/start_server.sh /usr/bin/start_server.sh
RUN chmod +x /usr/bin/start_server.sh /usr/bin/cuda_compat.sh

Expand All @@ -307,6 +308,7 @@ COPY code/serving.properties /opt/ml/model/serving.properties
# The container will automatically start DJL Serving with the configuration
<% } else { %>
COPY code/cuda_compat.sh /usr/bin/cuda_compat.sh
COPY code/cw_log_forwarder.py /usr/bin/cw_log_forwarder.py
COPY code/serve /usr/bin/serve
RUN chmod 777 /usr/bin/serve /usr/bin/cuda_compat.sh

Expand Down
64 changes: 64 additions & 0 deletions templates/code/cw_log_forwarder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env python3
"""CloudWatch log forwarder — workaround for IC platform log routing gap.
Pipes stdin to a CW log stream while passing through to stderr.
Usage: exec > >(python3 /usr/bin/cw_log_forwarder.py) 2>&1
"""
import sys, os, time, threading
import boto3
from botocore.config import Config

LOG_GROUP = os.environ.get("CW_LOG_GROUP",
f"/aws/sagemaker/InferenceComponents/{os.environ.get('INFERENCE_COMPONENT_NAME', os.environ.get('HOSTNAME', 'unknown'))}")
LOG_STREAM = f"AllTraffic/{os.environ.get('HOSTNAME', 'container')}"
REGION = os.environ.get("AWS_REGION", os.environ.get("AWS_DEFAULT_REGION", "us-west-2"))

def main():
client = boto3.client("logs", region_name=REGION, config=Config(retries={"max_attempts": 2}))
try:
client.create_log_group(logGroupName=LOG_GROUP)
except Exception:
pass
try:
client.create_log_stream(logGroupName=LOG_GROUP, logStreamName=LOG_STREAM)
except Exception as e:
# Can't create stream — just passthrough
for line in sys.stdin:
sys.stderr.write(line)
return

buf, lock, seq = [], threading.Lock(), [None]

def flush():
with lock:
if not buf:
return
batch = buf[:50]
del buf[:50]
events = [{"timestamp": int(t * 1000), "message": m} for t, m in batch]
kw = {"logGroupName": LOG_GROUP, "logStreamName": LOG_STREAM, "logEvents": events}
if seq[0]:
kw["sequenceToken"] = seq[0]
try:
r = client.put_log_events(**kw)
seq[0] = r.get("nextSequenceToken")
except Exception:
pass

def loop():
while True:
time.sleep(2)
flush()

threading.Thread(target=loop, daemon=True).start()
try:
for line in sys.stdin:
sys.stderr.write(line)
with lock:
buf.append((time.time(), line.rstrip("\n")))
except (KeyboardInterrupt, BrokenPipeError):
pass
finally:
flush()

if __name__ == "__main__":
main()
13 changes: 12 additions & 1 deletion templates/code/serve
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

# CloudWatch log forwarder — workaround for IC platform log routing gap
exec > >(python3 /usr/bin/cw_log_forwarder.py) 2>&1

echo "$(date -u '+%Y-%m-%dT%H:%M:%SZ') [serve] Container started — PID $$"

# CUDA compatibility setup (required for newer SageMaker inference AMIs)
source /usr/bin/cuda_compat.sh 2>/dev/null || true

Expand Down Expand Up @@ -270,8 +275,14 @@ for var in "${env_vars[@]}"; do

# Remove prefix, convert to lowercase, and replace underscores with dashes
arg_name=$(echo "${key#"${PREFIX}"}" | tr '[:upper:]' '[:lower:]' | tr '_' '-')

# Boolean handling: true = flag only, false = skip entirely
if [ "$value" = "false" ]; then
continue
fi

SERVER_ARGS+=("${ARG_PREFIX}${arg_name}")
if [ -n "$value" ]; then
if [ -n "$value" ] && [ "$value" != "true" ]; then
SERVER_ARGS+=("$value")
fi
done
Expand Down
Loading
Loading