GitHub user dosubot[bot] added a comment to the discussion: Superset API 
function write logs but not for FAB API

<!-- Answer -->
Superset API endpoints write logs because they use explicit logging decorators 
like `@event_logger.log_this_with_context` on their API methods. These 
decorators capture request and user context and write entries to the action log 
interface, which is why you see logs for endpoints like `/api/v1/dashboard/` 
[reference](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/log.py).

FAB API endpoints (such as `/api/v1/security/users/`) do not log actions by 
default because they lack these decorators. Logging is not automatic for FAB 
APIs; you need to add it manually. The recommended, upgrade-safe way is to 
either:

- Decorate the relevant CRUD methods (like `post`, `put`, `delete`) in your FAB 
API class with `@event_logger.log_this_with_context`, or
- Subclass the relevant FAB ModelView (for example, `UserDBModelView`) and 
override hooks like `after_model_create`, `after_model_change`, and 
`after_model_delete` to call the event logger. These hooks run after the 
transaction is committed, so they avoid transaction errors and have access to 
the request context 
[reference](https://github.com/apache/superset/issues/35594).

Here’s a concrete example for a custom FAB API endpoint:

```python
from flask import g, request
from superset.extensions import event_logger
from flask_appbuilder.security.views import UserDBModelView

class CustomUserDBModelView(UserDBModelView):
    def after_model_create(self, model):
        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",
            records=[{
                "actor_username": getattr(actor, "username", None),
                "target_username": getattr(model, "username", None),
                "ip_address": ip_address,
                "details": "User created",
            }],
            referrer=ip_address,
        )
    # Repeat for after_model_change and after_model_delete
```

Or, for an API method:

```python
from superset.extensions import event_logger

class CustomUserRestApi(UserRestApi):
    @event_logger.log_this_with_context(action="user_create", 
log_to_statsd=False)
    def post(self):
        response = super().post()
        # Optionally add extra audit details here
        return response
```

This will ensure your FAB API actions are logged in the Superset action log UI. 
Let me know if you want more details or help with a specific endpoint!


<!-- 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/96b9c701-46a9-4e9b-8451-3b519ed72b8d?feedback_type=great_response)
 | 
[Irrelevant](https://app.dosu.dev/response-feedback/96b9c701-46a9-4e9b-8451-3b519ed72b8d?feedback_type=irrelevant_answer)
 | 
[Incorrect](https://app.dosu.dev/response-feedback/96b9c701-46a9-4e9b-8451-3b519ed72b8d?feedback_type=incorrect_sources)
 | 
[Verbose](https://app.dosu.dev/response-feedback/96b9c701-46a9-4e9b-8451-3b519ed72b8d?feedback_type=too_verbose)
 | 
[Hallucination](https://app.dosu.dev/response-feedback/96b9c701-46a9-4e9b-8451-3b519ed72b8d?feedback_type=hallucination)
 | [Report 
🐛](https://app.dosu.dev/response-feedback/96b9c701-46a9-4e9b-8451-3b519ed72b8d?feedback_type=bug_report)
 | 
[Other](https://app.dosu.dev/response-feedback/96b9c701-46a9-4e9b-8451-3b519ed72b8d?feedback_type=other)</sup>

[![Chat with 
Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/a28d3c7e-a9d3-459e-9fb6-3a6f9ff4f357/ask?utm_source=github)&nbsp;[![Open
 in 
Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=Superset%20API%20endpoints%20write%20logs%20because%20they%20use%20explicit%20logging%20decorators%20like%20%60%40event_logger.log_this_with_context%60%20on%20their%20API%20methods.%20These%20decorators%20capture%20request%20and%20user%20context%20and%20write%20entries%20to%20the%20action%20log%20interface%2C%20which%20is%20why%20you%20see%20logs%20for%20endpoints%20like%20%60/api/v1/dashboard/%60%C2%A0%5Breference%5D%28https%3A//github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/log.py%29.%0A%0AFAB%20API%20endpoints%20%28such%20as%20%60/api/v1/security/users/%60%29%20do%20not%20log%20actions%20by%20default%20because%20they%20lack%20these%20decorators.%20Logging%20is%20not%20automatic%20for%20FAB%20APIs%3B%20you%20
 
need%20to%20add%20it%20manually.%20The%20recommended%2C%20upgrade-safe%20way%20is%20to%20either%3A%0A%0A-%20Decorate%20the%20relevant%20CRUD%20methods%20%28like%20%60post%60%2C%20%60put%60%2C%20%60delete%60%29%20in%20your%20FAB%20API%20class%20with%20%60%40event_logger.log_this_with_context%60%2C%20or%0A-%20Subclass%20the%20relevant%20FAB%20ModelView%20%28for%20example%2C%20%60UserDBModelView%60%29%20and%20override%20hooks%20like%20%60after_model_create%60%2C%20%60after_model_change%60%2C%20and%20%60after_model_delete%60%20to%20call%20the%20event%20logger.%20These%20hooks%20run%20after%20the%20transaction%20is%20committed%2C%20so%20they%20avoid%20transaction%20errors%20and%20have%20access%20to%20the%20request%20context%C2%A0%5Breference%5D%28https%3A//github.com/apache/superset/issues/35594%29.%0A%0AHere%E2%80%99s%20a%20concrete%20example%20for%20a%20custom%20FAB%20API%20endpoint%3A%0A%0A%60%60%60python%0Afrom%20flask%20import%20g%2C%20request%0Afrom%20superset.extensions%20import%2
 
0event_logger%0Afrom%20flask_appbuilder.security.views%20import%20UserDBModelView%0A%0Aclass%20CustomUserDBModelView%28UserDBModelView%29%3A%0A%20%20%20%20def%20after_model_create%28self%2C%20model%29%3A%0A%20%20%20%20%20%20%20%20actor%20%3D%20getattr%28g%2C%20%22user%22%2C%20None%29%0A%20%20%20%20%20%20%20%20ip_address%20%3D%20request.headers.get%28%22X-Forwarded-For%22%2C%20request.remote_addr%29%0A%20%20%20%20%20%20%20%20event_logger.log%28%0A%20%20%20%20%20%20%20%20%20%20%20%20user_id%3Dactor.id%20if%20actor%20else%20None%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20action%3D%22user_create%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20records%3D%5B%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22actor_username%22%3A%20getattr%28actor%2C%20%22username%22%2C%20None%29%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22target_username%22%3A%20getattr%28model%2C%20%22username%22%2C%20None%29%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22ip_address%22%3A%20ip_address
 
%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22details%22%3A%20%22User%20created%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20referrer%3Dip_address%2C%0A%20%20%20%20%20%20%20%20%29%0A%20%20%20%20%23%20Repeat%20for%20after_model_change%20and%20after_model_delete%0A%60%60%60%0A%0AOr%2C%20for%20an%20API%20method%3A%0A%0A%60%60%60python%0Afrom%20superset.extensions%20import%20event_logger%0A%0Aclass%20CustomUserRestApi%28UserRestApi%29%3A%0A%20%20%20%20%40event_logger.log_this_with_context%28action%3D%22user_create%22%2C%20log_to_statsd%3DFalse%29%0A%20%20%20%20def%20post%28self%29%3A%0A%20%20%20%20%20%20%20%20response%20%3D%20super%28%29.post%28%29%0A%20%20%20%20%20%20%20%20%23%20Optionally%20add%20extra%20audit%20details%20here%0A%20%20%20%20%20%20%20%20return%20response%0A%60%60%60%0A%0AThis%20will%20ensure%20your%20FAB%20API%20actions%20are%20logged%20in%20the%20Superset%20action%20log%20UI.%20Let%20me%20know%20if%20you%20want
 
%20more%20details%20or%20help%20with%20a%20specific%20endpoint%21)&nbsp;[![Join 
Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share
 on 
X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/apache/superset/discussions/36731)

GitHub link: 
https://github.com/apache/superset/discussions/36731#discussioncomment-15288254

----
This is an automatically sent email for [email protected].
To unsubscribe, please send an email to: 
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to