docs: def _log(pid, request, event, timestamp=None):
      """Log an operation that was performed on a sciobj."""
      # Support logging events that are not associated with an object.
      sciobj_model = None
      if pid is not None:
          try:
              sciobj_model = d1_gmn.app.models.ScienceObject.objects.filter(pid__did=pid)[
                  0
              ]
          except IndexError:
              raise d1_common.types.exceptions.ServiceFailure(
                  0,
                  'Attempted to create event log for non-existing object. pid="{}"'.format(
                      pid
                  ),
              )
  
      event_log_model = create_log_entry(
          sciobj_model,
          event,
          request.META['REMOTE_ADDR'],
          request.META.get('HTTP_USER_AGENT', '<not provided>'),
          request.primary_subject_str,
      )
  
      # The datetime is an optional parameter. If it is not provided, a
      # "auto_now_add=True" value in the the model defaults it to Now. The
      # disadvantage to this approach is that we have to update the timestamp in a
      # separate step if we want to set it to anything other than Now.
      if timestamp is not None:
          event_log_model.timestamp = timestamp
          event_log_model.save()