/** * Get request logs matching the given options in reverse chronological * order of request end time. * * @param array $options Optional associateive arrary of filters and * modifiers from following: * * <ul> * <li>'start_time': <code>DateTime or numeric</code> The earliest * completion time or last-update time for request logs. If the value is * numeric it represents microseconds since Unix epoch.</li> * <li>'end_time': <code>DateTime or numeric</code> The latest completion * time or last-update time for request logs. If the value is numeric it * represents microseconds since Unix epoch.</li> * <li>'offset': <code>string</code> The url-safe offset value from a * <code>RequestLog</code> to continue iterating after.</li> * <li>'minimum_log_level': <code>integer</code> Only return request logs * containing at least one application log of this severity or higher. * Works even if include_app_logs is not <code>true</code></li> * <li>'include_incomplete': <code>boolean</code> Should incomplete request * logs be included. The default is <code>false</code> - only completed * logs are returned</li> * <li>'include_app_logs': <code>boolean</code> Should application logs be * returned. The default is <code>false</code> - application logs are not * returned with their containing request logs.</li> * <li>'versions': <code>array</code> The versions of the default module * for which to fetch request logs. Only one of 'versions' and * 'module_versions' can be used.</li> * <li>'module_versions': <code>arrary/code> An associative array of module * names to versions for which to fetch request logs. Each module name may * be mapped to either a single <code>string</code> version or an <code> * array</code> of versions.</li> * <li>'batch_size': <code>integer</code> The number of request logs to * pre-fetch while iterating.</li> * </ul> * * @return Iterator The matching <code>RequestLog</code> items. */ public static function fetch(array $options = []) { $request = new LogReadRequest(); $request->setAppId(getenv('APPLICATION_ID')); // Required options default values - overridden by options below. $batch_size = 20; $include_app_logs = false; $include_incomplete = false; foreach ($options as $key => $value) { switch ($key) { case 'start_time': if (is_numeric($value)) { $usec = (double) $value; } else { if ($value instanceof \DateTime) { $usec = self::dateTimeToUsecs($value); } else { self::optionTypeException($key, $value, 'DateTime or numeric'); } } $request->setStartTime($usec); break; case 'end_time': if (is_numeric($value)) { $usec = (double) $value; } else { if ($value instanceof \DateTime) { $usec = self::dateTimeToUsecs($value); } else { self::optionTypeException($key, $value, 'DateTime or numeric'); } } $request->setEndTime($usec); break; case 'offset': if (!is_string($value)) { self::optionTypeException($key, $value, 'string'); } $decoded = StringUtil::base64UrlDecode($value); $request->mutableOffset()->parseFromString($decoded); break; case 'minimum_log_level': if (!is_int($value)) { self::optionTypeException($key, $value, 'integer'); } if ($value > self::LEVEL_CRITICAL || $value < self::LEVEL_DEBUG) { throw new \InvalidArgumentException("Option 'minimum_log_level' must be from " . self::LEVEL_DEBUG . " to " . self::LEVEL_CRITICAL); } $request->setMinimumLogLevel($value); break; case 'include_incomplete': if (!is_bool($value)) { self::optionTypeException($key, $value, 'boolean'); } $include_incomplete = $value; break; case 'include_app_logs': if (!is_bool($value)) { self::optionTypeException($key, $value, 'boolean'); } $include_app_logs = $value; break; case 'module_versions': if (!is_array($value)) { self::optionTypeException($key, $value, 'array'); } if (isset($options['versions'])) { throw new \InvalidArgumentException("Only one of 'versions' or " . "'module_versions' may be set"); } foreach ($value as $module => $versions) { if (!is_string($module)) { throw new \InvalidArgumentException('Server must be a string but was ' . self::typeOrClass($module)); } // Versions can be a single string or an array of strings. if (is_array($versions)) { foreach ($versions as $version) { if (!is_string($version)) { throw new \InvalidArgumentException('Server version must be a string but was ' . self::typeOrClass($version)); } $module_version = $request->addModuleVersion(); if ($module !== 'default') { $module_version->setModuleId($module); } $module_version->setVersionId($version); } } else { if (is_string($versions)) { $module_version = $request->addModuleVersion(); $module_version->setModuleId($module); $module_version->setVersionId($versions); } else { throw new \InvalidArgumentException('Server version must be a string or array but was ' . self::typeOrClass($versions)); } } } break; case 'versions': if (!is_array($value)) { self::optionTypeException($key, $value, 'array'); } if (isset($options['module_versions'])) { throw new \InvalidArgumentException("Only one of 'versions' or " . "'module_versions' may be set"); } foreach ($value as $version) { if (!is_string($version)) { throw new \InvalidArgumentException('Version must be a string but was ' . self::typeOrClass($version)); } if (!preg_match(self::$MAJOR_VERSION_ID_REGEX, $version)) { throw new \InvalidArgumentException("Invalid version id " . htmlspecialchars($version)); } $request->addModuleVersion()->setVersionId($version); } break; case 'batch_size': if (!is_int($value)) { self::optionTypeException($key, $value, 'integer'); } if ($value > self::MAX_BATCH_SIZE || $value < 1) { throw new \InvalidArgumentException('Batch size must be > 0 and <= ' . self::MAX_BATCH_SIZE); } $batch_size = $value; break; default: throw new \InvalidArgumentException("Invalid option " . htmlspecialchars($key)); } } // Set required options. $request->setIncludeIncomplete($include_incomplete); $request->setIncludeAppLogs($include_app_logs); $request->setCount($batch_size); // Set version to the current version if none set explicitly. if ($request->getModuleVersionSize() === 0) { self::setDefaultModuleVersion($request); } return new RequestLogIterator($request); }