Python Dash Dashboard Activity Log in Terminal

Hello,

I am working on a project and it is fully developed in Dash and hosted on an internal server. Whenever I interact with the site, there is an output in the terminal and it comprises an activity log. How could I export this to a .csv file or create something that tracks interactions/clicks on the dashboard to create an activity log?

Thank you!

1 Like

You need to be able to fetch the print logs from the server. How to do that, will depend on how your server has been set up.

With regards for finding the logs, you could add certain keywords to it. So the log could have a standardized format, like a dict:

{
    "log_type": "analytics",
    "timestamp": <time>,
}

You can then add all the information that you find relevant. In this example I used the "log_type" key to hold the keywords for the logs you are tracking.

If you want to add callback information to the log statement, like what outputs and inputs the callback has, you can define a customized decorator around the callback decorator (that’s what I did) and then you can put the print statement there. This will allow you to read the inputs and outputs. Here is an example of what I have done in the past. To use this, just replace @callback with @my_callback:

import json
from functools import wraps
import datetime

from dash import callback, Output
from dash.dependencies import handle_grouped_callback_args
from dash._utils import create_callback_id
from dash._grouping import flatten_grouping


function_register = {}


def my_callback(*callback_args, **callback_kwargs):

    def add_to_function_register(func):

        (
            outputs,
            inputs,
            states,
            *_
        ) = handle_grouped_callback_args(callback_args, callback_kwargs)

        # Now you can read the outputs, inputs, and states. For example, below
        # they are used to create a unique identifier for the callback and store
        # the callback in the function register. I used this to be able to catch
        # the callback when the server is running and the callback got triggered.
        # (I did that by reading the HTTP that was sent to the server when the 
        # callback was triggered.)

        if not isinstance(outputs, Output):
            outputs = flatten_grouping(outputs)

        # Store the components of the callback in the function register
        # Each callback will be given a unique identifier. Dash continuously
        # adds functionality to its callbacks, and to make sure we stay up to
        # date with how the unique id is created within Dash, we use Dash
        # functions for this.
        function_register[create_callback_id(outputs, inputs)] = {
            "callback_function_name": func.__name__,
            "outputs": outputs,
            "inputs": inputs,
            "state": states,
        }

        @callback(*callback_args, **callback_kwargs)
        @wraps(func)
        def wrapper(*args, **kwargs):
            # In here you have access to the values of the input parameters passed
            # to the callback and the result of the callback function.
            start_time = datetime.datetime.now()
            result = func(*args, **kwargs)
            duration = datetime.datetime.now() - start_time
            milliseconds = int(duration.total_seconds() * 1000)

            log_data = {"add your own log data here"}
            print(json.dumps(log_data))
            return result

    return add_to_function_register