1
0
Fork 0
mirror of synced 2024-05-21 05:02:37 +12:00

Added function execution logs

This commit is contained in:
Eldad Fux 2020-07-17 00:51:26 +03:00
parent 201c811582
commit 2caf909419
5 changed files with 95 additions and 28 deletions

View file

@ -233,35 +233,39 @@ $events = array_keys($this->getParam('events', []));
<h3>Logs</h3>
<div class="box">
<div class="box"
data-service="functions.listExecutions"
data-scope="sdk"
data-event="load,functions.createExecution"
data-name="project-function-executions"
data-param-function-id="{{router.params.id}}"
data-param-order-type="DESC"
data-success="trigger"
data-success-param-trigger-events="functions.listExecutions">
<table class="vertical small">
<thead>
<tr>
<th width="140">Date</th>
<th width="175">Event</th>
<th>Client</th>
<th width="90">Location</th>
<th width="90">IP</th>
<th width="140">Status</th>
<th width="170">Date</th>
<th width="100">Exit Code</th>
<th width="100">Runtime</th>
<th></th>
</tr>
</thead>
<!-- <tbody data-ls-loop="securityLogs" data-ls-as="log">
<tbody data-ls-loop="project-function-executions.executions" data-ls-as="execution">
<tr>
<td data-title="Date: "><span data-ls-bind="{{log.time|dateTime}}"></span></td>
<td data-title="Event: "><span data-ls-bind="{{log.event}}"></span></td>
<td data-title="Client: ">
<img data-ls-attrs="src={{env.API}}/avatars/browsers/{{log.client.short_name|lowercase}}?width=80&height=80&project={{env.PROJECT}},title={{log.client.name}},alt={{log.client.name}}" class="avatar xxs inline margin-end-small" />
<span data-ls-bind="{{log.client.name}} {{log.client.version}} on {{log.model}} {{log.OS.name}} {{log.OS.version}}"></span>
<td data-title="Status: "><span data-ls-bind="{{execution.status}}"></span></td>
<td data-title="Date: "><span data-ls-bind="{{execution.dateCreated|dateTime}}"></span></td>
<td data-title="Exit Code: "><span data-ls-bind="{{execution.exitCode}}"></span></td>
<td data-title="Runtime: "><span data-ls-bind="{{execution.time|seconds2hum}}"></span></td>
<td data-title="">
<a href="" class="text-danger pull-end margin-start">Errors</a>
<a href="" class="pull-end margin-start">Output</a>
</td>
<td data-title="Location: ">
<img data-ls-attrs="src={{env.API}}/avatars/flags/{{log.geo.isoCode}}?width=80&height=80&project={{env.PROJECT}}" class="avatar xxs inline margin-end-small" />
<span data-ls-bind="{{log.geo.country}}"></span>
</td>
<td data-title="IP: "><span data-ls-bind="{{log.ip}}"></span></td>
</tr>
</tbody> -->
</tbody>
</table>
</div>
</li>
<li data-state="/console/functions/function/settings?id={{router.params.id}}&project={{router.params.project}}">
<h2>Settings</h2>

View file

@ -61,6 +61,8 @@ class FunctionsV1
$projectId = $this->args['projectId'];
$functionId = $this->args['functionId'];
$functionTag = $this->args['functionTag'];
$executionId = $this->args['executionId'];
$functionTrigger = $this->args['functionTrigger'];
$projectDB = new Database();
$projectDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
@ -83,6 +85,32 @@ class FunctionsV1
throw new Exception('Tag not found', 404);
}
Authorization::disable();
$execution = $projectDB->getDocument($executionId);
if (empty($execution->getId()) || Database::SYSTEM_COLLECTION_EXECUTIONS != $execution->getCollection()) {
$execution = $projectDB->createDocument([
'$collection' => Database::SYSTEM_COLLECTION_EXECUTIONS,
'$permissions' => [
'read' => [],
'write' => [],
],
'dateCreated' => time(),
'functionId' => $function->getId(),
'status' => 'proccesing', // waiting / proccesing / completed / failed
'exitCode' => 0,
'stdout' => '',
'stderr' => '',
'time' => 0,
]);
if (false === $execution) {
throw new Exception('Failed saving execution to DB', 500);
}
}
Authorization::reset();
$environment = (isset($environments[$function->getAttribute('env', '')]))
? $environments[$function->getAttribute('env', '')]
: null;
@ -91,10 +119,10 @@ 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_TAG' => $functionTag,
'APPWRITE_FUNCTION_TRIGGER' => $functionTrigger,
'APPWRITE_FUNCTION_ENV_NAME' => $environment['name'],
'APPWRITE_FUNCTION_ENV_VERSION' => $environment['version'],
]);
@ -117,11 +145,11 @@ class FunctionsV1
*/
/**
* 1. Get event args
* 2. Unpackage code in the isolated container
* 1. Get event args - DONE
* 2. Unpackage code in the isolated container - DONE
* 3. Execute in container with timeout
* + messure execution time
* + pass env vars
* + messure execution time - DONE
* + pass env vars - DONE
* + pass one-time api key
* 4. Update execution status
* 5. Update execution stdout & stderr
@ -183,13 +211,28 @@ class FunctionsV1
$end = \microtime(true);
Authorization::disable();
$execution = $projectDB->updateDocument(array_merge($execution->getArrayCopy(), [
'status' => ($exitCode === 0) ? 'completed' : 'failed',
'exitCode' => $exitCode,
'stdout' => mb_substr($stdout, -2000), // log last 2000 chars output
'stderr' => mb_substr($stderr, -2000), // log last 2000 chars output
'time' => ($end - $start),
]));
Authorization::reset();
if (false === $function) {
throw new Exception('Failed saving execution to DB', 500);
}
/**
* Get Usage Stats
* -> Network (docker stats --no-stream --format="{{.NetIO}}" appwrite)
* -> CPU Time
* -> Invoctions (+1)
* Report to usage worker
* Save execution status and results
*/
var_dump('stdout', $stdout);

View file

@ -2619,7 +2619,7 @@ size;}).add("selectedCollection",function($value,router){return $value===router.
(hours?hours+"h ":"")+
(minutes?minutes+"m ":"")+
Number.parseFloat(seconds).toFixed(0)+"s");}
return"< 1s";}).add("markdown",function($value,markdown){return markdown.render($value);}).add("pageCurrent",function($value,env){return Math.ceil(parseInt($value||0)/env.PAGING_LIMIT)+1;}).add("pageTotal",function($value,env){let total=Math.ceil(parseInt($value||0)/env.PAGING_LIMIT);return total?total:1;}).add("humanFileSize",function($value){if(!$value){return 0;}
return"< 1s";}).add("seconds2hum",function($value){var seconds=($value).toFixed(2);var minutes=($value/(60)).toFixed(1);var hours=($value/(60*60)).toFixed(1);var days=($value/(60*60*24)).toFixed(1);if(seconds<60){return seconds+"s";}else if(minutes<60){return minutes+"m";}else if(hours<24){return hours+"h";}else{return days+"d"}}).add("markdown",function($value,markdown){return markdown.render($value);}).add("pageCurrent",function($value,env){return Math.ceil(parseInt($value||0)/env.PAGING_LIMIT)+1;}).add("pageTotal",function($value,env){let total=Math.ceil(parseInt($value||0)/env.PAGING_LIMIT);return total?total:1;}).add("humanFileSize",function($value){if(!$value){return 0;}
let thresh=1000;if(Math.abs($value)<thresh){return $value+" B";}
let units=["kB","MB","GB","TB","PB","EB","ZB","YB"];let u=-1;do{$value/=thresh;++u;}while(Math.abs($value)>=thresh&&u<units.length-1);return($value.toFixed(1)+'<span class="text-size-small unit">'+
units[u]+"</span>");}).add("statsTotal",function($value){if(!$value){return 0;}

View file

@ -257,7 +257,7 @@ size;}).add("selectedCollection",function($value,router){return $value===router.
(hours?hours+"h ":"")+
(minutes?minutes+"m ":"")+
Number.parseFloat(seconds).toFixed(0)+"s");}
return"< 1s";}).add("markdown",function($value,markdown){return markdown.render($value);}).add("pageCurrent",function($value,env){return Math.ceil(parseInt($value||0)/env.PAGING_LIMIT)+1;}).add("pageTotal",function($value,env){let total=Math.ceil(parseInt($value||0)/env.PAGING_LIMIT);return total?total:1;}).add("humanFileSize",function($value){if(!$value){return 0;}
return"< 1s";}).add("seconds2hum",function($value){var seconds=($value).toFixed(2);var minutes=($value/(60)).toFixed(1);var hours=($value/(60*60)).toFixed(1);var days=($value/(60*60*24)).toFixed(1);if(seconds<60){return seconds+"s";}else if(minutes<60){return minutes+"m";}else if(hours<24){return hours+"h";}else{return days+"d"}}).add("markdown",function($value,markdown){return markdown.render($value);}).add("pageCurrent",function($value,env){return Math.ceil(parseInt($value||0)/env.PAGING_LIMIT)+1;}).add("pageTotal",function($value,env){let total=Math.ceil(parseInt($value||0)/env.PAGING_LIMIT);return total?total:1;}).add("humanFileSize",function($value){if(!$value){return 0;}
let thresh=1000;if(Math.abs($value)<thresh){return $value+" B";}
let units=["kB","MB","GB","TB","PB","EB","ZB","YB"];let u=-1;do{$value/=thresh;++u;}while(Math.abs($value)>=thresh&&u<units.length-1);return($value.toFixed(1)+'<span class="text-size-small unit">'+
units[u]+"</span>");}).add("statsTotal",function($value){if(!$value){return 0;}

View file

@ -58,6 +58,26 @@ window.ls.filter
return "< 1s";
})
.add("seconds2hum", function($value) {
var seconds = ($value).toFixed(2);
var minutes = ($value / (60)).toFixed(1);
var hours = ($value / (60 * 60)).toFixed(1);
var days = ($value / (60 * 60 * 24)).toFixed(1);
if (seconds < 60) {
return seconds + "s";
} else if (minutes < 60) {
return minutes + "m";
} else if (hours < 24) {
return hours + "h";
} else {
return days + "d"
}
})
.add("markdown", function($value, markdown) {
return markdown.render($value);
})