mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Truncate logs to a limit
This commit is contained in:
@@ -618,7 +618,19 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
/** Update execution status */
|
||||
$status = $executionResponse['statusCode'] >= 500 ? 'failed' : 'completed';
|
||||
$execution->setAttribute('status', $status);
|
||||
$execution->setAttribute('logs', $executionResponse['logs']);
|
||||
|
||||
// Truncate logs if they exceed the limit
|
||||
$maxLogLength = APP_FUNCTION_LOG_LENGTH_LIMIT;
|
||||
$logs = $executionResponse['logs'] ?? '';
|
||||
|
||||
if (\is_string($logs) && \strlen($logs) > $maxLogLength) {
|
||||
$warningMessage = "\n[WARNING] Logs truncated. The output exceeded {$maxLogLength} characters.";
|
||||
$warningLength = \strlen($warningMessage);
|
||||
$maxContentLength = $maxLogLength - $warningLength;
|
||||
$logs = \substr($logs, 0, $maxContentLength) . $warningMessage;
|
||||
}
|
||||
|
||||
$execution->setAttribute('logs', $logs);
|
||||
$execution->setAttribute('errors', $executionResponse['errors']);
|
||||
$execution->setAttribute('responseStatusCode', $executionResponse['statusCode']);
|
||||
$execution->setAttribute('responseHeaders', $headersFiltered);
|
||||
|
||||
@@ -143,6 +143,7 @@ const APP_AUTH_TYPE_KEY = 'Key';
|
||||
const APP_AUTH_TYPE_ADMIN = 'Admin';
|
||||
// Response related
|
||||
const MAX_OUTPUT_CHUNK_SIZE = 10 * 1024 * 1024; // 10MB
|
||||
const APP_FUNCTION_LOG_LENGTH_LIMIT = 1000000;
|
||||
// Function headers
|
||||
const FUNCTION_ALLOWLIST_HEADERS_REQUEST = ['content-type', 'agent', 'content-length', 'host'];
|
||||
const FUNCTION_ALLOWLIST_HEADERS_RESPONSE = ['content-type', 'content-length'];
|
||||
|
||||
@@ -423,12 +423,22 @@ class Create extends Base
|
||||
}
|
||||
}
|
||||
|
||||
$maxLogLength = APP_FUNCTION_LOG_LENGTH_LIMIT;
|
||||
$logs = $executionResponse['logs'] ?? '';
|
||||
|
||||
if (\is_string($logs) && \strlen($logs) > $maxLogLength) {
|
||||
$warningMessage = "\n[WARNING] Logs truncated. The output exceeded {$maxLogLength} characters.";
|
||||
$warningLength = \strlen($warningMessage);
|
||||
$maxContentLength = $maxLogLength - $warningLength;
|
||||
$logs = \substr($logs, 0, $maxContentLength) . $warningMessage;
|
||||
}
|
||||
|
||||
/** Update execution status */
|
||||
$status = $executionResponse['statusCode'] >= 500 ? 'failed' : 'completed';
|
||||
$execution->setAttribute('status', $status);
|
||||
$execution->setAttribute('responseStatusCode', $executionResponse['statusCode']);
|
||||
$execution->setAttribute('responseHeaders', $headersFiltered);
|
||||
$execution->setAttribute('logs', $executionResponse['logs']);
|
||||
$execution->setAttribute('logs', $logs);
|
||||
$execution->setAttribute('errors', $executionResponse['errors']);
|
||||
$execution->setAttribute('duration', $executionResponse['duration']);
|
||||
} catch (\Throwable $th) {
|
||||
|
||||
@@ -551,11 +551,21 @@ class Functions extends Action
|
||||
}
|
||||
|
||||
/** Update execution status */
|
||||
$maxLogLength = APP_FUNCTION_LOG_LENGTH_LIMIT;
|
||||
$logs = $executionResponse['logs'] ?? '';
|
||||
|
||||
if (\is_string($logs) && \strlen($logs) > $maxLogLength) {
|
||||
$warningMessage = "\n[WARNING] Logs truncated. The output exceeded {$maxLogLength} characters.";
|
||||
$warningLength = \strlen($warningMessage);
|
||||
$maxContentLength = $maxLogLength - $warningLength;
|
||||
$logs = \substr($logs, 0, $maxContentLength) . $warningMessage;
|
||||
}
|
||||
|
||||
$execution
|
||||
->setAttribute('status', $status)
|
||||
->setAttribute('responseStatusCode', $executionResponse['statusCode'])
|
||||
->setAttribute('responseHeaders', $headersFiltered)
|
||||
->setAttribute('logs', $executionResponse['logs'])
|
||||
->setAttribute('logs', $logs)
|
||||
->setAttribute('errors', $executionResponse['errors'])
|
||||
->setAttribute('duration', $executionResponse['duration']);
|
||||
} catch (\Throwable $th) {
|
||||
|
||||
@@ -2282,4 +2282,34 @@ class FunctionsCustomServerTest extends Scope
|
||||
|
||||
$this->cleanupFunction($functionId);
|
||||
}
|
||||
|
||||
public function testLogTruncation(): void
|
||||
{
|
||||
$functionId = $this->setupFunction([
|
||||
'functionId' => ID::unique(),
|
||||
'name' => 'Test Log Truncation',
|
||||
'runtime' => 'node-22',
|
||||
'entrypoint' => 'index.js',
|
||||
'timeout' => 15,
|
||||
]);
|
||||
|
||||
$this->setupDeployment($functionId, [
|
||||
'code' => $this->packageFunction('log-truncation'),
|
||||
'activate' => true
|
||||
]);
|
||||
|
||||
$execution = $this->createExecution($functionId, [
|
||||
'async' => 'false'
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $execution['headers']['status-code']);
|
||||
$this->assertEquals(200, $execution['body']['responseStatusCode']);
|
||||
|
||||
// Verify logs are truncated and warning message is present
|
||||
$logs = $execution['body']['logs'];
|
||||
$this->assertLessThanOrEqual(APP_FUNCTION_LOG_LENGTH_LIMIT, strlen($logs));
|
||||
$this->assertStringContainsString('[WARNING] Logs truncated', $logs);
|
||||
|
||||
$this->cleanupFunction($functionId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
module.exports = async(context) => {
|
||||
// Create a string that is 1000001 characters long (exceeds the 1000000 limit)
|
||||
const longString = 'a'.repeat(1000001);
|
||||
|
||||
context.log(longString);
|
||||
|
||||
return context.res.json({
|
||||
motto: 'Build like a team of hundreds_',
|
||||
learn: 'https://appwrite.io/docs',
|
||||
connect: 'https://appwrite.io/discord',
|
||||
getInspired: 'https://builtwith.appwrite.io',
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user