/**
 * Log entry to system log table.
 *
 * @param array $params
 *
 * @return array
 */
function civicrm_api3_system_log($params)
{
    $log = new CRM_Utils_SystemLogger();
    // This part means fields with separate db storage are accepted as params which kind of seems more intuitive to me
    // because I felt like not doing this required a bunch of explanation in the spec function - but perhaps other won't see it as helpful?
    if (!isset($params['context'])) {
        $params['context'] = array();
    }
    $specialFields = array('contact_id', 'hostname');
    foreach ($specialFields as $specialField) {
        if (isset($params[$specialField]) && !isset($params['context'])) {
            $params['context'][$specialField] = $params[$specialField];
        }
    }
    $returnValues = $log->log($params['level'], $params['message'], $params['context']);
    return civicrm_api3_create_success($returnValues, $params, 'System', 'Log');
}
 /**
  * Handle processor error.
  *
  * If we pass error handling through this function it will be easy to switch to throwing exceptions later.
  *
  * @param string $level
  * @param string $message
  * @param string $context
  *
  * @param int $errorCode
  * @param string $userMessage
  *
  * @return mixed
  */
 protected function handleError($level, $message, $context, $errorCode = 9001, $userMessage = NULL)
 {
     if (omnipaymultiprocessor__versionAtLeast(4.5)) {
         $log = new CRM_Utils_SystemLogger();
         $log->log($level, $message, (array) $context);
     } else {
         CRM_Core_Error::debug($errorCode . ': ' . $message . print_r($context, TRUE));
     }
     CRM_Core_Session::setStatus(empty($userMessage) ? $message : $userMessage);
     return new CRM_Core_Error();
 }