Added function execution logs
This commit is contained in:
parent
201c811582
commit
2caf909419
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
2
public/dist/scripts/app-all.js
vendored
2
public/dist/scripts/app-all.js
vendored
|
@ -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;}
|
||||
|
|
2
public/dist/scripts/app.js
vendored
2
public/dist/scripts/app.js
vendored
|
@ -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;}
|
||||
|
|
|
@ -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);
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue