getString('class'); $cls = Module::resolveClass($cls, 'Stats\Output', '\SimpleSAML\Stats\Output'); $output = new $cls($config); return $output; } /** * Initialize the outputs. * * @throws \Exception */ private static function initOutputs(): void { $config = Configuration::getInstance(); $outputCfgs = $config->getOptionalArray('statistics.out', []); self::$outputs = []; foreach ($outputCfgs as $cfg) { self::$outputs[] = self::createOutput(Configuration::loadFromArray($cfg)); } } /** * Notify about an event. * * @param string $event The event. * @param array $data Event data. Optional. * * @return false|null * @throws \Exception */ public static function log(string $event, array $data = []): bool|null { Assert::keyNotExists($data, 'op'); Assert::keyNotExists($data, 'time'); Assert::keyNotExists($data, '_id'); if (!self::$initialized) { self::initOutputs(); self::$initialized = true; } if (empty(self::$outputs)) { // not enabled return false; } $data['op'] = $event; $data['time'] = microtime(true); // the ID generation is designed to cluster IDs related in time close together $int_t = (int) $data['time']; $hd = openssl_random_pseudo_bytes(16); $data['_id'] = sprintf('%016x%s', $int_t, bin2hex($hd)); foreach (self::$outputs as $out) { $out->emit($data); } return null; } }