Загрузка данных
def get_app(opts):
"""
Returns a WSGI app and a configuration dictionary
"""
apiopts = opts.get(__name__.rsplit(".", 2)[-2], {}) # rest_cherrypy opts
# Add Salt and salt-api config options to the main CherryPy config dict
cherrypy.config["saltopts"] = opts
cherrypy.config["apiopts"] = apiopts
# --- START: ADD CUSTOM LOG FORMAT ---
# Store username in the request object for later use in logging
def store_username():
"""Extract username from request and store it in cherrypy.request"""
if cherrypy.request.method == "POST" and cherrypy.request.path_info == "/run":
lowstate = getattr(cherrypy.request, "lowstate", None)
if isinstance(lowstate, list) and lowstate:
first_chunk = lowstate[0]
username = first_chunk.get("username")
if not username and "kwarg" in first_chunk:
username = first_chunk["kwarg"].get("username")
if username:
cherrypy.request._salt_username = username
else:
# Check if token auth is used (no username in request)
token = first_chunk.get("token")
if token:
cherrypy.request._salt_username = "token-auth"
else:
cherrypy.request._salt_username = "-"
else:
cherrypy.request._salt_username = "-"
else:
cherrypy.request._salt_username = "-"
# Hook into CherryPy's before_handler phase
cherrypy.tools.store_username = cherrypy.Tool("before_handler", store_username, priority=10)
# Custom log format that includes username
# %h = remote host, %l = remote logname (always '-'), %u = remote user (we inject this)
# %t = timestamp, %r = request line, %s = status, %b = bytes, %{Referer}i = referer, %{User-Agent}i = user-agent
def custom_log_access():
"""Override the default access log format to include username"""
# Get the default access log format and inject our username
from cherrypy.lib import httputil
request = cherrypy.serving.request
response = cherrypy.serving.response
# Get the username we stored earlier
username = getattr(request, "_salt_username", "-")
# Build the log line
remote_host = request.remote.name or request.remote.ip or "-"
user = username # This goes in the 'remote user' field
request_line = "%s %s %s" % (request.method, request.path_info, request.query_string)
if request.query_string:
request_line = "%s %s?%s" % (request.method, request.path_info, request.query_string)
# Log using the standard CherryPy access log
cherrypy.log.access(
'%s - %s [%s] "%s" %s %s "%s" "%s"' % (
remote_host,
user,
httputil.HTTPDate(),
request_line,
response.status,
response.headers.get("Content-Length") or "-",
request.headers.get("Referer", "-"),
request.headers.get("User-Agent", "-"),
)
)
# Prevent duplicate logging
return False
# Replace the default access log tool
from cherrypy._cpaccess import AccessTool
# Disable the default access logger
cherrypy.tools.access_log = cherrypy.Tool("on_end_request", lambda: None, priority=20)
# Add our custom access logger
cherrypy.tools.custom_access_log = cherrypy.Tool("on_end_request", custom_log_access, priority=21)
# Enable our tools in the global config
cherrypy.config.update({
"tools.store_username.on": True,
"tools.custom_access_log.on": True,
})
# --- END: ADD CUSTOM LOG FORMAT ---
root = API() # cherrypy app
cpyopts = root.get_conf() # cherrypy app opts
return root, apiopts, cpyopts