<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def log(self, level, msg, *args, **kwargs):
 """Log a message and inform all clients. Parameters level : logging level constant The level to log the message at. msg : str The text format for the log message. args : list of objects Arguments to pass to log format string. Final message text is created using: msg % args. kwargs : additional keyword parameters Allowed keywords are 'name' and 'timestamp'. The name is the name of the logger to log the message to. If not given the name defaults to the root logger. The timestamp is a float in seconds. If not given the timestamp defaults to the current time. """

        timestamp = kwargs.get("timestamp")
        python_msg = msg
        if self._python_logger is not None:
            if timestamp is not None:
                python_msg = ' '.join((
                    'katcp timestamp: %r' % timestamp,
                    python_msg))
            self._python_logger.log(self.PYTHON_LEVEL[level], python_msg, *args)
        if level >= self._log_level:
            name = kwargs.get("name")
            if name is None:
                name = self._root_logger_name
            try:
                inform_msg = msg % args
            except TypeError:
                # Catch the "not enough arguments for format string" exception.
                inform_msg = "{} {}".format(
                    msg,
                    args if args else '').strip()

            self._device_server.mass_inform(
                self._device_server.create_log_inform(
                    self.level_name(level),
                    inform_msg,
                    name,
                    timestamp=timestamp))