diff --git a/app/app.php b/app/app.php index 8d0e376a1..4b48929ce 100644 --- a/app/app.php +++ b/app/app.php @@ -235,10 +235,11 @@ App::init(function ($utopia, $request, $response, $console, $project, $user, $lo $usage ->setParam('projectId', $project->getId()) - ->setParam('url', $request->getHostname().$request->getURI()) - ->setParam('method', $request->getMethod()) - ->setParam('request', 0) - ->setParam('response', 0) + ->setParam('httpRequest', 1) + ->setParam('httpUrl', $request->getHostname().$request->getURI()) + ->setParam('httpMethod', $request->getMethod()) + ->setParam('networkRequestSize', 0) + ->setParam('networkResponseSize', 0) ->setParam('storage', 0) ; }, ['utopia', 'request', 'response', 'console', 'project', 'user', 'locale', 'webhooks', 'audits', 'usage', 'clients']); @@ -273,8 +274,8 @@ App::shutdown(function ($utopia, $request, $response, $project, $webhooks, $audi && !empty($route->getLabel('sdk.namespace', null))) { // Don't calculate console usage and admin mode $usage - ->setParam('request', $request->getSize() + $usage->getParam('storage')) - ->setParam('response', $response->getSize()) + ->setParam('networkRequestSize', $request->getSize() + $usage->getParam('storage')) + ->setParam('networkResponseSize', $response->getSize()) ->trigger() ; } diff --git a/app/workers/functions.php b/app/workers/functions.php index d36e68957..902fa479f 100644 --- a/app/workers/functions.php +++ b/app/workers/functions.php @@ -13,13 +13,13 @@ use Utopia\Config\Config; require_once __DIR__.'/../init.php'; -cli_set_process_title('Functions V1 Worker'); +\cli_set_process_title('Functions V1 Worker'); Console::success(APP_NAME.' functions worker v1 has started'); $environments = Config::getParam('environments'); -$warmupStart = microtime(true); +$warmupStart = \microtime(true); Co\run(function() use ($environments) { foreach($environments as $environment) { // Warmup: make sure images are ready to run fast 🚀 @@ -42,7 +42,7 @@ Co\run(function() use ($environments) { } }); -$warmupEnd = microtime(true); +$warmupEnd = \microtime(true); $warmupTime = $warmupEnd - $warmupStart; Console::success('Finished warmup in '.$warmupTime.' seconds'); @@ -67,8 +67,8 @@ Console::success('Finished warmup in '.$warmupTime.' seconds'); * + messure execution time - DONE * + pass env vars - DONE * + pass one-time api key - * 4. Update execution status - * 5. Update execution stdout & stderr + * 4. Update execution status - DONE + * 5. Update execution stdout & stderr - DONE * 6. Trigger audit log * 7. Trigger usage log */ @@ -145,7 +145,7 @@ class FunctionsV1 'read' => [], 'write' => [], ], - 'dateCreated' => time(), + 'dateCreated' => \time(), 'functionId' => $function->getId(), 'status' => 'processing', // waiting / processing / completed / failed 'exitCode' => 0, @@ -169,7 +169,7 @@ class FunctionsV1 throw new Exception('Environment "'.$function->getAttribute('env', '').' is not supported'); } - $vars = array_merge($function->getAttribute('vars', []), [ + $vars = \array_merge($function->getAttribute('vars', []), [ 'APPWRITE_FUNCTION_ID' => $functionId, 'APPWRITE_FUNCTION_NAME' => $function->getAttribute('name', ''), 'APPWRITE_FUNCTION_TAG' => $functionTag, @@ -178,7 +178,7 @@ class FunctionsV1 'APPWRITE_FUNCTION_ENV_VERSION' => $environment['version'], ]); - array_walk($vars, function (&$value, $key) { + \array_walk($vars, function (&$value, $key) { $value = (empty($value)) ? 'null' : $value; $value = "\t\t\t--env {$key}={$value} \\"; }); @@ -187,7 +187,7 @@ class FunctionsV1 $tagPathTarget = '/tmp/project-'.$projectId.'/'.$tag->getId().'/code.tar.gz'; $tagPathTargetDir = \pathinfo($tagPathTarget, PATHINFO_DIRNAME); $container = 'appwrite-function-'.$tag->getId(); - $command = escapeshellcmd($tag->getAttribute('command', '')); + $command = \escapeshellcmd($tag->getAttribute('command', '')); if(!\is_readable($tagPath)) { throw new Exception('Code is not readable: '.$tag->getAttribute('codePath', '')); @@ -216,28 +216,28 @@ class FunctionsV1 $executionEnd = \microtime(true); $list = []; - $stdout = explode("\n", $stdout); + $stdout = \explode("\n", $stdout); - array_map(function($value) use (&$list) { + \array_map(function($value) use (&$list) { $container = []; - parse_str($value, $container); + \parse_str($value, $container); if(isset($container['name'])) { $container = [ 'name' => $container['name'], - 'online' => (substr($container['status'], 0, 2) === 'Up'), + 'online' => (\substr($container['status'], 0, 2) === 'Up'), 'status' => $container['status'], 'labels' => $container['labels'], ]; - array_map(function($value) use (&$container) { - $value = explode('=', $value); + \array_map(function($value) use (&$container) { + $value = \explode('=', $value); if(isset($value[0]) && isset($value[1])) { $container[$value[0]] = $value[1]; } - }, explode(',', $container['labels'])); + }, \explode(',', $container['labels'])); $list[$container['name']] = $container; } @@ -245,8 +245,6 @@ class FunctionsV1 Console::info("Functions listed in " . ($executionEnd - $executionStart) . " seconds with exit code {$exitCode}"); - //TODO if container found and offline -> delete it - if(isset($list[$container]) && !$list[$container]['online']) { $stdout = ''; $stderr = ''; @@ -258,8 +256,6 @@ class FunctionsV1 unset($list[$container]); } - //TODO if more than x contianers -> clear all older containers - if(!isset($list[$container])) { // Create contianer if not ready $stdout = ''; $stderr = ''; @@ -275,10 +271,10 @@ class FunctionsV1 --rm \ --name={$container} \ --label appwrite-type=function \ - --label appwrite-created=".time()." \ + --label appwrite-created=".\time()." \ --volume {$tagPathTargetDir}:/tmp:rw \ --workdir /usr/local/src \ - ".implode("\n", $vars)." + ".\implode("\n", $vars)." {$environment['image']} \ sh -c 'mv /tmp/code.tar.gz /usr/local/src/code.tar.gz && tar -zxf /usr/local/src/code.tar.gz --strip 1 && rm /usr/local/src/code.tar.gz && tail -f /dev/null'" , null, $stdout, $stderr, 30); @@ -301,7 +297,7 @@ class FunctionsV1 $executionStart = \microtime(true); $exitCode = Console::execute("docker exec {$container} {$command}" - , null, $stdout, $stderr, $function->getAttribute('timeout', (int) App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900))); // TODO add app env for max timeout + , null, $stdout, $stderr, $function->getAttribute('timeout', (int) App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900))); $executionEnd = \microtime(true); @@ -328,7 +324,7 @@ class FunctionsV1 $max = (int) App::getEnv('_APP_FUNCTIONS_CONTAINERS'); - if(count($list) > $max) { + if(\count($list) > $max) { Console::info('Starting containers cleanup'); $sorted = []; @@ -340,12 +336,12 @@ class FunctionsV1 ]; } - usort($sorted, function ($item1, $item2) { + \usort($sorted, function ($item1, $item2) { return $item1['created'] <=> $item2['created']; }); - while(count($sorted) > $max) { - $first = array_shift($sorted); + while(\count($sorted) > $max) { + $first = \array_shift($sorted); $stdout = ''; $stderr = ''; diff --git a/app/workers/usage.php b/app/workers/usage.php index 5206f9f01..56da254f4 100644 --- a/app/workers/usage.php +++ b/app/workers/usage.php @@ -27,21 +27,35 @@ class UsageV1 $statsd = $register->get('statsd', true); $projectId = $this->args['projectId']; - $method = $this->args['method']; - $request = $this->args['request']; - $response = $this->args['response']; + $httpMethod = $this->args['httpMethod']; + $httpRequest = $this->args['httpRequest']; + + $networkRequestSize = $this->args['networkRequestSize']; + $networkResponseSize = $this->args['networkResponseSize']; + $storage = $this->args['storage']; + $functionExecution = $this->args['functionExecution']; + $functionExecutionTime = $this->args['functionExecutionTime']; + $functionId = $this->args['functionId']; + $tags = ",project={$projectId},version=".App::getEnv('_APP_VERSION', 'UNKNOWN').''; // the global namespace is prepended to every key (optional) $statsd->setNamespace('appwrite.usage'); - $statsd->increment('requests.all'.$tags.',method='.\strtolower($method)); + if($httpRequest >= 1) { + $statsd->increment('requests.all'.$tags.',method='.\strtolower($httpMethod)); + } + + if($functionExecution >= 1) { + $statsd->increment('executions.all'.$tags.',functionId='.$functionId); + $statsd->count('executions.time'.$tags.',functionId='.$functionId, $functionExecutionTime); + } - $statsd->count('network.all'.$tags, $request + $response); - $statsd->count('network.inbound'.$tags, $request); - $statsd->count('network.outbound'.$tags, $response); + $statsd->count('network.all'.$tags, $networkRequestSize + $networkResponseSize); + $statsd->count('network.inbound'.$tags, $networkRequestSize); + $statsd->count('network.outbound'.$tags, $networkResponseSize); $statsd->count('storage.all'.$tags, $storage); }