From fb4a7d492847b26be5378e49610b258c344ef280 Mon Sep 17 00:00:00 2001 From: rajeswari1301 Date: Fri, 7 Aug 2026 13:48:39 -0500 Subject: [PATCH] Add request ID to nginx and docassemble logs --- Docker/config/nginx-http.dist | 1 + Docker/config/nginx-ssl.dist | 1 + docassemble_base/docassemble/base/functions.py | 2 +- docassemble_webapp/docassemble/webapp/server.py | 10 ++++++---- .../docassemble/webapp/worker_tasks.py | 12 ++++++++---- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Docker/config/nginx-http.dist b/Docker/config/nginx-http.dist index 98c243394..6c95c76ca 100644 --- a/Docker/config/nginx-http.dist +++ b/Docker/config/nginx-http.dist @@ -11,6 +11,7 @@ server { location {{DAWSGIROOT}} { try_files $uri @docassemble; } location @docassemble { include uwsgi_params; + uwsgi_param HTTP_X_REQUEST_ID $request_id; uwsgi_pass unix:///var/run/uwsgi/docassemble.sock; } diff --git a/Docker/config/nginx-ssl.dist b/Docker/config/nginx-ssl.dist index e7be5cf54..686b6ddcf 100644 --- a/Docker/config/nginx-ssl.dist +++ b/Docker/config/nginx-ssl.dist @@ -18,6 +18,7 @@ server { return 301 https://{{DAHOSTNAME}}$request_uri; } include uwsgi_params; + uwsgi_param HTTP_X_REQUEST_ID $request_id; uwsgi_pass unix:///var/run/uwsgi/docassemble.sock; } diff --git a/docassemble_base/docassemble/base/functions.py b/docassemble_base/docassemble/base/functions.py index 8b99fcd41..fe2614839 100644 --- a/docassemble_base/docassemble/base/functions.py +++ b/docassemble_base/docassemble/base/functions.py @@ -2305,7 +2305,7 @@ def date_done(self): def worker_caller(func, ui_notification, action): # logmessage("Got to worker_caller in functions") result = MyAsyncResult() - result.obj = func.delay(this_thread.current_info['yaml_filename'], this_thread.current_info['user'], this_thread.current_info['session'], this_thread.current_info['secret'], this_thread.current_info['url'], this_thread.current_info['url_root'], action, extra=ui_notification) + result.obj = func.delay(this_thread.current_info['yaml_filename'], this_thread.current_info['user'], this_thread.current_info['session'], this_thread.current_info['secret'], this_thread.current_info['url'], this_thread.current_info['url_root'], action, extra=ui_notification, requestid=this_thread.current_info.get('requestid')) if ui_notification is not None: worker_key = 'da:worker:uid:' + str(this_thread.current_info['session']) + ':i:' + str(this_thread.current_info['yaml_filename']) + ':userid:' + str(this_thread.current_info['user']['the_user_id']) # logmessage("worker_caller: id is " + str(result.obj.id) + " and key is " + worker_key) diff --git a/docassemble_webapp/docassemble/webapp/server.py b/docassemble_webapp/docassemble/webapp/server.py index 2939d9022..511c4d793 100644 --- a/docassemble_webapp/docassemble/webapp/server.py +++ b/docassemble_webapp/docassemble/webapp/server.py @@ -1367,7 +1367,7 @@ def syslog_message(message): else: the_user = "anonymous" the_current_info = getattr(docassemble.base.functions.this_thread, 'current_info', {}) - sys_logger.debug('%s', LOGFORMAT % {'message': message, 'clientip': get_requester_ip(request), 'yamlfile': the_current_info.get('yaml_filename', 'na'), 'user': the_user, 'session': the_current_info.get('session', 'na')}) + sys_logger.debug('%s', LOGFORMAT % {'message': message, 'clientip': get_requester_ip(request), 'yamlfile': the_current_info.get('yaml_filename', 'na'), 'user': the_user, 'session': the_current_info.get('session', 'na'), 'requestid': the_current_info.get('requestid', 'na')}) except BaseException as err: sys.stderr.write("Error writing log message " + str(message) + "\n") try: @@ -1376,7 +1376,8 @@ def syslog_message(message): pass else: try: - sys_logger.debug('%s', LOGFORMAT % {'message': message, 'clientip': 'localhost', 'yamlfile': 'na', 'user': 'na', 'session': 'na'}) + the_current_info = getattr(docassemble.base.functions.this_thread, 'current_info', {}) + sys_logger.debug('%s', LOGFORMAT % {'message': message, 'clientip': 'localhost', 'yamlfile': the_current_info.get('yaml_filename', 'na'), 'user': 'na', 'session': the_current_info.get('session', 'na'), 'requestid': the_current_info.get('requestid', 'na')}) except BaseException as err: sys.stderr.write("Error writing log message " + str(message) + "\n") try: @@ -1388,7 +1389,7 @@ def syslog_message(message): def syslog_message_with_timestamp(message): syslog_message(time.strftime("%Y-%m-%d %H:%M:%S") + " " + message) -LOGFORMAT = daconfig.get('log format', 'docassemble: ip=%(clientip)s i=%(yamlfile)s uid=%(session)s user=%(user)s %(message)s') +LOGFORMAT = daconfig.get('log format', 'docassemble: ip=%(clientip)s i=%(yamlfile)s uid=%(session)s user=%(user)s rid=%(requestid)s %(message)s') class UnsilenceableLogger(logging.Logger): @@ -4677,6 +4678,7 @@ def current_info(yaml=None, req=None, action=None, location=None, interface='web if session_uid == '': session_uid = app.session_interface.manual_save_session(app, session).decode()[5:15] # logmessage("unique id is " + session_uid) + requestid = headers.get('X-Request-Id') if device_id is None: device_id = random_string(16) if secret is not None: @@ -4689,7 +4691,7 @@ def current_info(yaml=None, req=None, action=None, location=None, interface='web else: user_code = None encrypted = True - return_val = {'session': user_code, 'secret': secret, 'yaml_filename': yaml, 'interface': interface, 'url': url, 'url_root': url_root, 'encrypted': encrypted, 'user': {'is_anonymous': bool(current_user.is_anonymous), 'is_authenticated': bool(current_user.is_authenticated), 'session_uid': session_uid, 'device_id': device_id}, 'headers': headers, 'clientip': clientip, 'method': method} + return_val = {'session': user_code, 'secret': secret, 'yaml_filename': yaml, 'interface': interface, 'url': url, 'url_root': url_root, 'encrypted': encrypted, 'requestid': requestid, 'user': {'is_anonymous': bool(current_user.is_anonymous), 'is_authenticated': bool(current_user.is_authenticated), 'session_uid': session_uid, 'device_id': device_id}, 'headers': headers, 'clientip': clientip, 'method': method} if action is not None: # logmessage("current_info: setting an action " + repr(action)) return_val.update(action) diff --git a/docassemble_webapp/docassemble/webapp/worker_tasks.py b/docassemble_webapp/docassemble/webapp/worker_tasks.py index 97907f170..d61676813 100644 --- a/docassemble_webapp/docassemble/webapp/worker_tasks.py +++ b/docassemble_webapp/docassemble/webapp/worker_tasks.py @@ -1048,7 +1048,7 @@ def email_attachments(user_code, email_address, attachment_info, language, subje @workerapp.task -def background_action(yaml_filename, user_info, session_code, secret, url, url_root, action, extra=None): +def background_action(yaml_filename, user_info, session_code, secret, url, url_root, action, extra=None, requestid=None): if url_root is None: url_root = daconfig.get('url root', 'http://localhost') + daconfig.get('root', '/') if url is None: @@ -1063,12 +1063,16 @@ def background_action(yaml_filename, user_info, session_code, secret, url, url_r user_object = worker_controller.get_user_object(user_info['theid']) worker_controller.login_user(user_object, remember=False) worker_controller.update_last_login(user_object) - logmessage("background_action: yaml_filename is " + str(yaml_filename) + " and session code is " + str(session_code) + " and action is " + repr(action)) + if str(user_info.get('the_user_id', '')).startswith('t'): + user_identifier = "temp user " + str(user_info.get('theid')) + else: + user_identifier = "user " + str(user_info.get('theid')) + logmessage("background_action: yaml_filename is " + str(yaml_filename) + " and session code is " + str(session_code) + " and " + user_identifier + " and action is " + repr(action)) worker_controller.set_request_active(False) if action['action'] == 'incoming_email': if 'id' in action['arguments']: action['arguments'] = {'email': worker_controller.retrieve_email(action['arguments']['id'])} - the_current_info = {'user': user_info, 'session': session_code, 'secret': secret, 'yaml_filename': yaml_filename, 'url': url, 'url_root': url_root, 'encrypted': True, 'action': action['action'], 'interface': 'worker', 'arguments': action['arguments']} + the_current_info = {'user': user_info, 'session': session_code, 'secret': secret, 'yaml_filename': yaml_filename, 'url': url, 'url_root': url_root, 'encrypted': True, 'action': action['action'], 'interface': 'worker', 'arguments': action['arguments'], 'requestid': requestid} worker_controller.functions.this_thread.current_info = the_current_info interview = worker_controller.interview_cache.get_interview(yaml_filename) worker_controller.obtain_lock_patiently(session_code, yaml_filename) @@ -1141,7 +1145,7 @@ def background_action(yaml_filename, user_info, session_code, secret, url, url_r start_time = time.time() new_action = interview_status.question.action # logmessage("new action is " + repr(new_action)) - the_current_info = {'user': user_info, 'session': session_code, 'secret': secret, 'yaml_filename': yaml_filename, 'url': url, 'url_root': url_root, 'encrypted': True, 'interface': 'worker', 'action': new_action['action'], 'arguments': new_action['arguments']} + the_current_info = {'user': user_info, 'session': session_code, 'secret': secret, 'yaml_filename': yaml_filename, 'url': url, 'url_root': url_root, 'encrypted': True, 'interface': 'worker', 'action': new_action['action'], 'arguments': new_action['arguments'], 'requestid': requestid} worker_controller.functions.this_thread.current_info = the_current_info worker_controller.obtain_lock_patiently(session_code, yaml_filename) steps, user_dict, is_encrypted = worker_controller.fetch_user_dict(session_code, yaml_filename, secret=secret)