diff --git a/docs/building-apps/canister-management/settings.mdx b/docs/building-apps/canister-management/settings.mdx
index a691a6a265..dc34a735e1 100644
--- a/docs/building-apps/canister-management/settings.mdx
+++ b/docs/building-apps/canister-management/settings.mdx
@@ -13,7 +13,7 @@ import { GlossaryTooltip } from "/src/components/Tooltip/GlossaryTooltip";
Each canister has a group of possible settings that control its behavior. Only a controller of the canister can read and modify a canister's settings.
-Currently, there are nine canister setting fields:
+Currently, there are ten canister settings fields:
1. `controllers`: The list of controllers of the canister.
2. `compute_allocation`: Amount of compute that the canister has allocated.
@@ -22,8 +22,9 @@ Currently, there are nine canister setting fields:
5. `reserved_cycles_limit`: A safety threshold to protect against spending too many cycles for resource reservation.
6. `wasm_memory_limit`: A safety threshold to protect against reaching the 4GiB hard limit of 32-bit Wasm memory.
7. `log_visibility`: Controls who can read the canister logs.
-8. `wasm_memory_threshold`: A threshold that triggers the "on low wasm memory" hook when the canister's remaining wasm memory falls below the provided value.
-9. `environment_variables`: A set of key-value pairs that configure canister behavior without code changes.
+8. `log_memory_limit`: The maximum amount of memory used for canister logs.
+9. `wasm_memory_threshold`: A threshold that triggers the "on low wasm memory" hook when the canister's remaining wasm memory falls below the provided value.
+10. `environment_variables`: A set of key-value pairs that configure canister behavior without code changes.
## Viewing current settings
@@ -211,4 +212,4 @@ The default value of the field is `controllers`.
Common errors related to canister settings include:
-- [Invalid settings](/docs/references/execution-errors#invalid-settings).
\ No newline at end of file
+- [Invalid settings](/docs/references/execution-errors#invalid-settings).
diff --git a/docs/references/_attachments/ic.did b/docs/references/_attachments/ic.did
index 4622a2f78c..558770112f 100644
--- a/docs/references/_attachments/ic.did
+++ b/docs/references/_attachments/ic.did
@@ -20,6 +20,7 @@ type canister_settings = record {
freezing_threshold : opt nat;
reserved_cycles_limit : opt nat;
log_visibility : opt log_visibility;
+ log_memory_limit : opt nat;
wasm_memory_limit : opt nat;
wasm_memory_threshold : opt nat;
environment_variables : opt vec environment_variable;
@@ -32,6 +33,7 @@ type definite_canister_settings = record {
freezing_threshold : nat;
reserved_cycles_limit : nat;
log_visibility : log_visibility;
+ log_memory_limit : nat;
wasm_memory_limit : nat;
wasm_memory_threshold : nat;
environment_variables : vec environment_variable;
diff --git a/docs/references/ic-interface-spec.md b/docs/references/ic-interface-spec.md
index 32edc73e9a..4d9669e0e5 100644
--- a/docs/references/ic-interface-spec.md
+++ b/docs/references/ic-interface-spec.md
@@ -2412,6 +2412,13 @@ The optional `settings` parameter can be used to set the following settings:
Default value: `controllers`.
+- `log_memory_limit` (`nat`)
+
+ Must be equal to 4096 and indicates the maximum amount of memory used for canister logs.
+ Oldest canister logs are purged if the total memory used for canister logs exceeds this value.
+
+ Default value: `4096`.
+
- `wasm_memory_threshold` (`nat`)
Must be a number between 0 and 264-1, inclusively, and indicates the threshold on the remaining wasm memory size of the canister in bytes:
@@ -3152,8 +3159,8 @@ This method can only be called by external users via non-replicated calls, i.e.,
Given a canister ID as input, this method returns a vector of logs of that canister including its trap messages.
The canister logs are *not* collected in canister methods running in non-replicated mode (NRQ, CQ, CRy, CRt, CC, and F modes, as defined in [Overview of imports](#system-api-imports)) and the canister logs are *purged* when the canister is reinstalled or uninstalled.
-The total size of all returned logs does not exceed 4KiB.
-If new logs are added resulting in exceeding the maximum total log size of 4KiB, the oldest logs will be removed.
+The total size of all returned logs does not exceed the value `log_memory_limit` in canister settings.
+Oldest canister logs are purged if the total memory used for canister logs exceeds the value `log_memory_limit` in canister settings.
Logs persist across canister upgrades and they are deleted if the canister is reinstalled or uninstalled.
The log visibility is defined in the `log_visibility` field of `canister_settings` and can be one of the following variants:
@@ -4035,6 +4042,7 @@ S = {
certified_data: CanisterId ↦ Blob;
canister_history: CanisterId ↦ CanisterHistory;
canister_log_visibility: CanisterId ↦ CanisterLogVisibility;
+ canister_log_memory_limit: CanisterId ↦ Nat;
canister_logs: CanisterId ↦ [CanisterLog];
query_stats: CanisterId ↦ [QueryStats];
system_time : Timestamp
@@ -4143,6 +4151,7 @@ The initial state of the IC is
certified_data = ();
canister_history = ();
canister_log_visibility = ();
+ canister_log_memory_limit = ();
canister_logs = ();
query_stats = ();
system_time = T;
@@ -5134,6 +5143,11 @@ if A.settings.log_visibility is not null:
else:
New_canister_log_visibility = Controllers
+if A.settings.log_memory_limit is not null:
+ New_canister_log_memory_limit = A.settings.log_memory_limit
+else:
+ New_canister_log_memory_limit = 4096
+
```
State after
@@ -5161,6 +5175,7 @@ S' = S with
query_stats[Canister_id] = []
canister_history[Canister_id] = New_canister_history
canister_log_visibility[Canister_id] = New_canister_log_visibility
+ canister_log_memory_limit[Canister_id] = New_canister_log_memory_limit
canister_logs[Canister_id] = []
messages = Older_messages · Younger_messages ·
ResponseMessage {
@@ -5305,6 +5320,8 @@ S' = S with
canister_version[A.canister_id] = S.canister_version[A.canister_id] + 1
if A.settings.log_visibility is not null:
canister_log_visibility[A.canister_id] = A.settings.log_visibility
+ if A.settings.log_memory_limit is not null:
+ canister_log_memory_limit[A.canister_id] = A.settings.log_memory_limit
messages = Older_messages · Younger_messages ·
ResponseMessage {
origin = M.origin
@@ -6182,6 +6199,7 @@ S with
certified_data[A.canister_id] = (deleted)
canister_history[A.canister_id] = (deleted)
canister_log_visibility[A.canister_id] = (deleted)
+ canister_log_memory_limit[A.canister_id] = (deleted)
canister_logs[A.canister_id] = (deleted)
query_stats[A.canister_id] = (deleted)
chunk_store[A.canister_id] = (deleted)
@@ -6417,6 +6435,11 @@ if A.settings.log_visibility is not null:
else:
New_canister_log_visibility = Controllers
+if A.settings.log_memory_limit is not null:
+ New_canister_log_memory_limit = A.settings.log_memory_limit
+else:
+ New_canister_log_memory_limit = 4096
+
```
State after
@@ -6442,6 +6465,7 @@ S' = S with
certified_data[Canister_id] = ""
canister_history[Canister_id] = New_canister_history
canister_log_visibility[Canister_id] = New_canister_log_visibility
+ canister_log_memory_limit[Canister_id] = New_canister_log_memory_limit
canister_logs[Canister_id] = []
query_stats[CanisterId] = []
messages = Older_messages · Younger_messages ·
@@ -7322,16 +7346,19 @@ S with
```
-#### Trimming canister logs
+#### Purging canister logs
+
+Oldest canister logs are purged if the total memory used for canister logs exceeds the value `log_memory_limit` in canister settings.
-Canister logs can be trimmed if their total length exceeds 4KiB.
+The (unspecified) function `canister_log_memory_usage(logs)` models the total memory used by `logs`.
Conditions
```html
S.canister_logs[CanisterId] = Older_logs · Newer_logs
-SUM { |l| | l <- Older_logs } > 4KiB
+canister_log_memory_usage(Older_logs · Newer_logs) > S.canister_log_memory_limit[CanisterId]
+canister_log_memory_usage(Newer_logs) ≤ S.canister_log_memory_limit[CanisterId]
```