dosubot[bot] commented on issue #35594: URL: https://github.com/apache/superset/issues/35594#issuecomment-3395615562
<!-- Answer --> Here's a concrete example for robust user management action logging in Superset, avoiding transaction errors and capturing audit details like actor and IP address: Subclass the relevant API class (e.g., `SupersetUserApi` or `UserRestApi`), override the CRUD methods (`post`, `put`, `delete`), and use the `event_logger.log_this_with_context` decorator to log actions with full request context. This ensures logging happens after the transaction is committed and avoids the "transaction is closed" error you saw with SQLAlchemy event listeners [reference](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/views/users/api.py). Example: ```python from flask import g, request from superset.extensions import event_logger from superset.views.users.api import UserRestApi class CustomUserRestApi(UserRestApi): @event_logger.log_this_with_context( action="user_create", log_to_statsd=False, ) def post(self): # Your user creation logic here response = super().post() # Optionally add extra audit details actor = getattr(g, "user", None) ip_address = request.headers.get("X-Forwarded-For", request.remote_addr) event_logger.log( user_id=actor.id if actor else None, action="user_create", json={ "actor_username": getattr(actor, "username", None), "ip_address": ip_address, "details": "User created", }, referrer=ip_address, ) return response @event_logger.log_this_with_context( action="user_update", log_to_statsd=False, ) def put(self, user_id): # Your user update logic here response = super().put(user_id) actor = getattr(g, "user", None) ip_address = request.headers.get("X-Forwarded-For", request.remote_addr) event_logger.log( user_id=actor.id if actor else None, action="user_update", json={ "actor_username": getattr(actor, "username", None), "ip_address": ip_address, "details": f"User {user_id} updated", }, referrer=ip_address, ) return response @event_logger.log_this_with_context( action="user_delete", log_to_statsd=False, ) def delete(self, user_id): # Your user deletion logic here response = super().delete(user_id) actor = getattr(g, "user", None) ip_address = request.headers.get("X-Forwarded-For", request.remote_addr) event_logger.log( user_id=actor.id if actor else None, action="user_delete", json={ "actor_username": getattr(actor, "username", None), "ip_address": ip_address, "details": f"User {user_id} deleted", }, referrer=ip_address, ) return response ``` This pattern is upgrade-safe and integrates with Superset's Action Log. You can register your custom API class in your fork or extension by replacing the default view registration for user management. The `event_logger.log_this_with_context` decorator automatically captures request context and user info, and you can add extra details to the log entry as shown above [reference](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/log.py). Let me know if you need help with registering your custom API or want an example for a different method! <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/74fd352f-1e9f-4541-8347-9be9322bd03b?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/74fd352f-1e9f-4541-8347-9be9322bd03b?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/74fd352f-1e9f-4541-8347-9be9322bd03b?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/74fd352f-1e9f-4541-8347-9be9322bd03b?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/74fd352f-1e9f-4541-8347-9be9322bd03b?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/74fd352f-1e9f-4541-8347-9be9322bd03b?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/74fd352f-1e9f-4541-8347-9be9322bd03b?feedback_type=other)</sup> [](https://app.dosu.dev/a28d3c7e-a9d3-459e-9fb6-3a6f9ff4f357/ask?utm_source=githu b) [](https://go.dosu.dev/discord-bot) [](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/apache/superset/issues/35594) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
