From a88394478c408a28f8100d1ef9d562d14530874b Mon Sep 17 00:00:00 2001 From: Marco Walz Date: Tue, 16 Jun 2026 19:53:42 +0200 Subject: [PATCH] chore: migrate rust/canister_logs to icp-cli MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace dfx.json with icp.yaml using @dfinity/rust@v3.3.0 - Move src/lib.rs → backend/lib.rs; add workspace Cargo.toml - Upgrade dependencies: ic-cdk 0.20, ic-cdk-timers 1.0, ic-cdk-management-canister 0.1.1 - Replace ic_cdk::api::management_canister with ic_cdk_management_canister::raw_rand - Add Makefile with 11 tests covering all public canister methods - Rewrite README with icp-cli deploy/test instructions - Add rust-canister_logs CI job (icp-dev-env-rust:1.0.0) to canister_logs.yml - Delete dfx.json, BUILD.md, poll_logs.sh, canister_logs.did, .devcontainer/ Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/canister_logs.yml | 15 + .../.devcontainer/devcontainer.json | 20 - rust/canister_logs/BUILD.md | 113 ---- rust/canister_logs/Cargo.lock | 511 ++++++++++-------- rust/canister_logs/Cargo.toml | 16 +- rust/canister_logs/Makefile | 136 ++--- rust/canister_logs/README.md | 174 ++---- rust/canister_logs/backend/Cargo.toml | 14 + rust/canister_logs/{src => backend}/lib.rs | 7 +- rust/canister_logs/canister_logs.did | 10 - rust/canister_logs/dfx.json | 10 - rust/canister_logs/icp.yaml | 8 + rust/canister_logs/package-lock.json | 7 - rust/canister_logs/poll_logs.sh | 26 - rust/canister_logs/rust-toolchain.toml | 2 - 15 files changed, 441 insertions(+), 628 deletions(-) delete mode 100644 rust/canister_logs/.devcontainer/devcontainer.json delete mode 100644 rust/canister_logs/BUILD.md create mode 100644 rust/canister_logs/backend/Cargo.toml rename rust/canister_logs/{src => backend}/lib.rs (92%) delete mode 100644 rust/canister_logs/canister_logs.did delete mode 100644 rust/canister_logs/dfx.json create mode 100644 rust/canister_logs/icp.yaml delete mode 100644 rust/canister_logs/package-lock.json delete mode 100755 rust/canister_logs/poll_logs.sh diff --git a/.github/workflows/canister_logs.yml b/.github/workflows/canister_logs.yml index 52eb58c5f..89e4f410b 100644 --- a/.github/workflows/canister_logs.yml +++ b/.github/workflows/canister_logs.yml @@ -6,6 +6,7 @@ on: pull_request: paths: - motoko/canister_logs/** + - rust/canister_logs/** - .github/workflows/canister_logs.yml concurrency: @@ -26,3 +27,17 @@ jobs: icp network start -d icp deploy make test + + rust-canister_logs: + runs-on: ubuntu-24.04 + container: ghcr.io/dfinity/icp-dev-env-rust:1.0.0 + env: + ICP_CLI_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + - name: Deploy and test + working-directory: rust/canister_logs + run: | + icp network start -d + icp deploy + make test diff --git a/rust/canister_logs/.devcontainer/devcontainer.json b/rust/canister_logs/.devcontainer/devcontainer.json deleted file mode 100644 index ebb0b8bcc..000000000 --- a/rust/canister_logs/.devcontainer/devcontainer.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "ICP Dev Environment", - "image": "ghcr.io/dfinity/icp-dev-env-slim:22", - "forwardPorts": [4943, 5173], - "portsAttributes": { - "4943": { - "label": "dfx", - "onAutoForward": "ignore" - }, - "5173": { - "label": "vite", - "onAutoForward": "openBrowser" - } - }, - "customizations": { - "vscode": { - "extensions": ["dfinity-foundation.vscode-motoko"] - } - } -} diff --git a/rust/canister_logs/BUILD.md b/rust/canister_logs/BUILD.md deleted file mode 100644 index 24cfcb754..000000000 --- a/rust/canister_logs/BUILD.md +++ /dev/null @@ -1,113 +0,0 @@ -# Continue building locally - -Projects deployed through ICP Ninja are temporary; they will only be live for 20 minutes before they are removed. The command-line tool `dfx` can be used to continue building your ICP Ninja project locally and deploy it to the mainnet. - -To migrate your ICP Ninja project off of the web browser and develop it locally, follow these steps. - -### 1. Install developer tools. - -You can install the developer tools natively or use Dev Containers. - -#### Option 1: Natively install developer tools - -> Installing `dfx` natively is currently only supported on macOS and Linux systems. On Windows, it is recommended to use the Dev Containers option. - -1. Install `dfx` with the following command: - -``` - -sh -ci "$(curl -fsSL https://internetcomputer.org/install.sh)" - -``` - -> On Apple Silicon (e.g., Apple M1 chip), make sure you have Rosetta installed (`softwareupdate --install-rosetta`). - -2. [Install NodeJS](https://nodejs.org/en/download/package-manager). - -3. For Rust projects, you will also need to: - -- Install [Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html#install-rust-and-cargo): `curl https://sh.rustup.rs -sSf | sh` - -- Install [candid-extractor](https://crates.io/crates/candid-extractor): `cargo install candid-extractor` - -4. For Motoko projects, you will also need to: - -- Install the Motoko package manager [Mops](https://docs.mops.one/quick-start#2-install-mops-cli): `npm i -g ic-mops` - -Lastly, navigate into your project's directory that you downloaded from ICP Ninja. - -#### Option 2: Dev Containers - -Continue building your projects locally by installing the [Dev Container extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) for VS Code and [Docker](https://docs.docker.com/engine/install/). - -Make sure Docker is running, then navigate into your project's directory that you downloaded from ICP Ninja and start the Dev Container by selecting `Dev-Containers: Reopen in Container` in VS Code's command palette (F1 or Ctrl/Cmd+Shift+P). - -> Note that local development ports (e.g. the ports used by `dfx` or `vite`) are forwarded from the Dev Container to your local machine. In the VS code terminal, use Ctrl/Cmd+Click on the displayed local URLs to open them in your browser. To view the current port mappings, click the "Ports" tab in the VS Code terminal window. - -### 2. Start the local development environment. - -``` -dfx start --background -``` - -### 3. Create a local developer identity. - -To manage your project's canisters, it is recommended that you create a local [developer identity](https://internetcomputer.org/docs/building-apps/getting-started/identities) rather than use the `dfx` default identity that is not stored securely. - -To create a new identity, run the commands: - -``` - -dfx identity new IDENTITY_NAME - -dfx identity use IDENTITY_NAME - -``` - -Replace `IDENTITY_NAME` with your preferred identity name. The first command `dfx start --background` starts the local `dfx` processes, then `dfx identity new` will create a new identity and return your identity's seed phase. Be sure to save this in a safe, secure location. - -The third command `dfx identity use` will tell `dfx` to use your new identity as the active identity. Any canister smart contracts created after running `dfx identity use` will be owned and controlled by the active identity. - -Your identity will have a principal ID associated with it. Principal IDs are used to identify different entities on ICP, such as users and canisters. - -[Learn more about ICP developer identities](https://internetcomputer.org/docs/building-apps/getting-started/identities). - -### 4. Deploy the project locally. - -Deploy your project to your local developer environment with: - -``` -npm install -dfx deploy - -``` - -Your project will be hosted on your local machine. The local canister URLs for your project will be shown in the terminal window as output of the `dfx deploy` command. You can open these URLs in your web browser to view the local instance of your project. - -### 5. Obtain cycles. - -To deploy your project to the mainnet for long-term public accessibility, first you will need [cycles](https://internetcomputer.org/docs/building-apps/getting-started/tokens-and-cycles). Cycles are used to pay for the resources your project uses on the mainnet, such as storage and compute. - -> This cost model is known as ICP's [reverse gas model](https://internetcomputer.org/docs/building-apps/essentials/gas-cost), where developers pay for their project's gas fees rather than users pay for their own gas fees. This model provides an enhanced end user experience since they do not need to hold tokens or sign transactions when using a dapp deployed on ICP. - -> Learn how much a project may cost by using the [pricing calculator](https://internetcomputer.org/docs/building-apps/essentials/cost-estimations-and-examples). - -Cycles can be obtained through [converting ICP tokens into cycles using `dfx`](https://internetcomputer.org/docs/building-apps/developer-tools/dfx/dfx-cycles#dfx-cycles-convert). - -### 6. Deploy to the mainnet. - -Once you have cycles, run the command: - -``` - -dfx deploy --network ic - -``` - -After your project has been deployed to the mainnet, it will continuously require cycles to pay for the resources it uses. You will need to [top up](https://internetcomputer.org/docs/building-apps/canister-management/topping-up) your project's canisters or set up automatic cycles management through a service such as [CycleOps](https://cycleops.dev/). - -> If your project's canisters run out of cycles, they will be removed from the network. - -## Additional examples - -Additional code examples and sample applications can be found in the [DFINITY examples repo](https://github.com/dfinity/examples). diff --git a/rust/canister_logs/Cargo.lock b/rust/canister_logs/Cargo.lock index 06ea8bc55..edb192ab0 100644 --- a/rust/canister_logs/Cargo.lock +++ b/rust/canister_logs/Cargo.lock @@ -1,12 +1,21 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "ar_archive_writer" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4087686b4b0a3427190bae57a1d9a478dbb2d40c5dc1bd6e2b6d797913bdd348" +dependencies = [ + "object", +] [[package]] name = "arrayvec" @@ -16,9 +25,19 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "autocfg" -version = "1.3.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "backend" +version = "0.1.0" +dependencies = [ + "candid", + "ic-cdk", + "ic-cdk-management-canister", + "ic-cdk-timers", +] [[package]] name = "binread" @@ -60,9 +79,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "candid" -version = "0.10.8" +version = "0.10.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd5902d37352dffd8bd9177a2daa6444ce3cd0279c91763fb0171c053aa04335" +checksum = "f8f781afa4a1303e3eab4ada0720a874942bcfa936ce01b816ac6378945c43a9" dependencies = [ "anyhow", "binread", @@ -78,181 +97,126 @@ dependencies = [ "serde", "serde_bytes", "stacker", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "candid_derive" -version = "0.6.6" +version = "0.10.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3de398570c386726e7a59d9887b68763c481477f9a043fb998a2e09d428df1a9" +checksum = "ad6ae8e7944dd0035651bc0e7b3a3e4cb16f5fc43f8ae4fd76b36ff2cd52759f" dependencies = [ "lazy_static", "proc-macro2", "quote", - "syn 2.0.65", -] - -[[package]] -name = "canister_logs" -version = "1.1.0" -dependencies = [ - "candid", - "ic-cdk 0.12.1", - "ic-cdk-macros 0.8.4", - "ic-cdk-timers", + "syn 2.0.118", ] [[package]] name = "cc" -version = "1.0.98" +version = "1.2.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f" +dependencies = [ + "find-msvc-tools", + "shlex", +] [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "typenum", ] [[package]] -name = "data-encoding" -version = "2.6.0" +name = "darling" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" dependencies = [ - "block-buffer", - "crypto-common", + "darling_core", + "darling_macro", ] [[package]] -name = "either" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" - -[[package]] -name = "futures" -version = "0.3.30" +name = "darling_core" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.118", ] [[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" +name = "darling_macro" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ - "futures-core", - "futures-task", - "futures-util", + "darling_core", + "quote", + "syn 2.0.118", ] [[package]] -name = "futures-io" -version = "0.3.30" +name = "data-encoding" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" [[package]] -name = "futures-macro" -version = "0.3.30" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.65", + "block-buffer", + "crypto-common", ] [[package]] -name = "futures-sink" -version = "0.3.30" +name = "either" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] -name = "futures-task" -version = "0.3.30" +name = "find-msvc-tools" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "generic-array" @@ -264,6 +228,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hex" version = "0.4.3" @@ -272,120 +242,145 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "ic-cdk" -version = "0.12.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3d204af0b11c45715169c997858edb58fa8407d08f4fae78a6b415dd39a362" +checksum = "6a7971f4983db147afbbc4e7f87f60b09fcd60ac707af37ff3d2468dcddbf551" dependencies = [ "candid", - "ic-cdk-macros 0.8.4", + "ic-cdk-executor", + "ic-cdk-macros", + "ic-error-types", "ic0", + "pin-project-lite", "serde", - "serde_bytes", + "thiserror 2.0.18", ] [[package]] -name = "ic-cdk" -version = "0.13.2" +name = "ic-cdk-executor" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8859bc2b863a77750acf199e1fb7e3fc403e1b475855ba13f59cb4e4036d238" +checksum = "33716b730ded33690b8a704bff3533fda87d229e58046823647d28816e9bcee7" dependencies = [ - "candid", - "ic-cdk-macros 0.13.2", "ic0", - "serde", - "serde_bytes", + "slotmap", + "smallvec", ] [[package]] name = "ic-cdk-macros" -version = "0.8.4" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5a618e4020cea88e933d8d2f8c7f86d570ec06213506a80d4f2c520a9bba512" +checksum = "a7c20c002200c720958f321bb78b4d4987fc2c380bf9ef69ed4404730810f45f" dependencies = [ "candid", + "darling", "proc-macro2", "quote", - "serde", - "serde_tokenstream", - "syn 1.0.109", + "syn 2.0.118", ] [[package]] -name = "ic-cdk-macros" -version = "0.13.2" +name = "ic-cdk-management-canister" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a45800053d80a6df839a71aaea5797e723188c0b992618208ca3b941350c7355" +checksum = "92c1319a274caebf0ab70ab826b8905c29e8563498289356b9a59464f2a85c56" dependencies = [ "candid", - "proc-macro2", - "quote", + "ic-cdk", + "ic-management-canister-types", "serde", - "serde_tokenstream", - "syn 1.0.109", + "serde_bytes", + "thiserror 2.0.18", ] [[package]] name = "ic-cdk-timers" -version = "0.7.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054727a3a1c486528b96349817d54290ff70df6addf417def456ea708a16f7fb" +checksum = "6852b9c1d4a82ff50fc7318599298aee8bfb082bd7e9fe7e5c1420692b2170f7" dependencies = [ - "futures", - "ic-cdk 0.13.2", + "ic-cdk-executor", "ic0", + "slotmap", +] + +[[package]] +name = "ic-error-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbeeb3d91aa179d6496d7293becdacedfc413c825cac79fd54ea1906f003ee55" +dependencies = [ + "serde", + "strum", + "strum_macros", +] + +[[package]] +name = "ic-management-canister-types" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51705516ed4d23f24e8d714a70fe9d7ec17106cfd830d5434a1b29f583ef70ee" +dependencies = [ + "candid", "serde", "serde_bytes", - "slotmap", ] [[package]] name = "ic0" -version = "0.21.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a54b5297861c651551676e8c43df805dad175cc33bc97dbd992edbbb85dcbcdf" +checksum = "c77c8932bff1f09502d0d8c079d5a206a06afe523e35e816162cf4d30b5bf80d" [[package]] name = "ic_principal" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1762deb6f7c8d8c2bdee4b6c5a47b60195b74e9b5280faa5ba29692f8e17429c" +checksum = "1aea751965eaf92990be8c79c64b4f3174ff22dd3604e6696a06a494afbaba2a" dependencies = [ "crc32fast", "data-encoding", "serde", "sha2", - "thiserror", + "thiserror 1.0.69", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "leb128" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" +checksum = "c83bff1d572d6b9aeef67ddfc8448e4a3737909cb28e81f97c791b9018703e52" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "memchr" -version = "2.7.2" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" [[package]] name = "num-bigint" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", @@ -410,6 +405,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + [[package]] name = "paste" version = "1.0.15" @@ -418,21 +422,15 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pretty" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55c4d17d994b637e2f4daf6e5dc5d660d209d5642377d675d7a1c3ab69fa579" +checksum = "0d22152487193190344590e4f30e219cf3fe140d9e7a3fdb683d82aa2c5f4156" dependencies = [ "arrayvec", "typed-arena", @@ -441,82 +439,83 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.83" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] [[package]] name = "psm" -version = "0.1.21" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +checksum = "645dbe486e346d9b5de3ef16ede18c26e6c70ad97418f4874b8b1889d6e761ea" dependencies = [ + "ar_archive_writer", "cc", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "serde" -version = "1.0.202" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.14" +version = "0.11.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" dependencies = [ "serde", + "serde_core", ] [[package]] -name = "serde_derive" -version = "1.0.202" +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.65", + "serde_derive", ] [[package]] -name = "serde_tokenstream" -version = "0.1.7" +name = "serde_derive" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "797ba1d80299b264f3aac68ab5d12e5825a561749db4df7cd7c8083900c5d4e9" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", - "serde", - "syn 1.0.109", + "quote", + "syn 2.0.118", ] [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -524,34 +523,65 @@ dependencies = [ ] [[package]] -name = "slab" -version = "0.4.9" +name = "shlex" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "slotmap" -version = "1.0.7" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" dependencies = [ "version_check", ] +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + [[package]] name = "stacker" -version = "0.1.15" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +checksum = "640c8cdd92b6b12f5bcb1803ca3bbf5ab96e5e6b6b96b9ab77dabe9e880b3190" dependencies = [ "cc", "cfg-if", "libc", "psm", - "winapi", + "windows-sys", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.118", ] [[package]] @@ -567,9 +597,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.65" +version = "2.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" dependencies = [ "proc-macro2", "quote", @@ -578,22 +608,42 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.118", ] [[package]] @@ -604,46 +654,39 @@ checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" [[package]] name = "typenum" -version = "1.17.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-width" -version = "0.1.12" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "winapi" -version = "0.3.9" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "windows-link" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "windows-sys" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] diff --git a/rust/canister_logs/Cargo.toml b/rust/canister_logs/Cargo.toml index 89cc20a2e..d1e49e317 100644 --- a/rust/canister_logs/Cargo.toml +++ b/rust/canister_logs/Cargo.toml @@ -1,13 +1,3 @@ -[package] -edition = "2021" -name = "canister_logs" -version = "1.1.0" - -[lib] -crate-type = ["cdylib"] - -[dependencies] -candid = "0.10" -ic-cdk = "0.12" -ic-cdk-macros = "0.8" -ic-cdk-timers = "0.7" +[workspace] +members = ["backend"] +resolver = "2" diff --git a/rust/canister_logs/Makefile b/rust/canister_logs/Makefile index d07e1b2d9..d93662f38 100644 --- a/rust/canister_logs/Makefile +++ b/rust/canister_logs/Makefile @@ -1,78 +1,82 @@ -.PHONY: all -all: deploy - -.PHONY: deploy -.SILENT: deploy -deploy: - dfx deploy canister_logs - .PHONY: test -.SILENT: test -test: deploy - # Test print via update call. - dfx canister call canister_logs print 'print via update' - dfx canister logs canister_logs \ - | grep 'print via update' && echo 'PASS' - # Test print via replicated query call. - dfx canister call --update canister_logs print_query 'print via replicated query' - dfx canister logs canister_logs \ - | grep 'print via replicated query' && echo 'PASS' +test: + @echo "=== Test 1: print via update call is recorded in logs ===" + @icp canister call backend print '("print via update")' && \ + result=$$(icp canister logs backend) && \ + echo "$$result" && \ + echo "$$result" | grep -q 'print via update' && \ + echo "PASS" || (echo "FAIL" && exit 1) - # Test print via non-replicated query call should NOT record the message. - dfx canister call --query canister_logs print_query 'print via non-replicated query' - ! dfx canister logs canister_logs \ - | grep 'print via non-replicated query' && echo 'PASS' + @echo "=== Test 2: print via replicated query call is recorded in logs ===" + @icp canister call --update backend print_query '("print via replicated query")' && \ + result=$$(icp canister logs backend) && \ + echo "$$result" && \ + echo "$$result" | grep -q 'print via replicated query' && \ + echo "PASS" || (echo "FAIL" && exit 1) - # Test trapped call is recorded in logs. - # Ignore failed dfx command output (so the test continues) and check the logs to contain the message. - - dfx canister call canister_logs trap 'trap via update' - dfx canister logs canister_logs \ - | grep 'trap via update' && echo 'PASS' + @echo "=== Test 3: print via non-replicated query should NOT be recorded in logs ===" + @icp canister call --query backend print_query '("print via non-replicated query")'; \ + result=$$(icp canister logs backend) && \ + echo "$$result" && \ + ! echo "$$result" | grep -q 'print via non-replicated query' && \ + echo "PASS" || (echo "FAIL" && exit 1) - # Test trap via replicated query call. - # Ignore failed dfx command output (so the test continues) and check the logs to contain the message. - - dfx canister call --update canister_logs trap_query 'trap via replicated query' - dfx canister logs canister_logs \ - | grep 'trap via replicated query' && echo 'PASS' + @echo "=== Test 4: trap via update call is recorded in logs ===" + @icp canister call backend trap '("trap via update")' 2>/dev/null; \ + result=$$(icp canister logs backend) && \ + echo "$$result" && \ + echo "$$result" | grep -q 'trap via update' && \ + echo "PASS" || (echo "FAIL" && exit 1) - # Test trap via non-replicated query call should NOT record the message. - # Ignore failed dfx command output (so the test continues) and check the logs to contain the message. - - dfx canister call --query canister_logs trap_query 'trap via non-replicated query' - ! dfx canister logs canister_logs \ - | grep 'trap via non-replicated query' && echo 'PASS' + @echo "=== Test 5: trap via replicated query call is recorded in logs ===" + @icp canister call --update backend trap_query '("trap via replicated query")' 2>/dev/null; \ + result=$$(icp canister logs backend) && \ + echo "$$result" && \ + echo "$$result" | grep -q 'trap via replicated query' && \ + echo "PASS" || (echo "FAIL" && exit 1) - # Test the call with panic is recorded in logs. - # Ignore failed dfx command output (so the test continues) and check the logs to contain the message. - - dfx canister call canister_logs panic 'panic via update' - dfx canister logs canister_logs \ - | grep 'panic via update' && echo 'PASS' + @echo "=== Test 6: trap via non-replicated query should NOT be recorded in logs ===" + @icp canister call --query backend trap_query '("trap via non-replicated query")' 2>/dev/null; \ + result=$$(icp canister logs backend) && \ + echo "$$result" && \ + ! echo "$$result" | grep -q 'trap via non-replicated query' && \ + echo "PASS" || (echo "FAIL" && exit 1) - # Test call to fail with memory out of bounds. - # Ignore failed dfx command output (so the test continues) and check the logs to contain the message. - - dfx canister call canister_logs memory_oob - dfx canister logs canister_logs \ - | grep 'stable memory out of bounds' && echo 'PASS' + @echo "=== Test 7: panic via update call is recorded in logs ===" + @icp canister call backend panic '("panic via update")' 2>/dev/null; \ + result=$$(icp canister logs backend) && \ + echo "$$result" && \ + echo "$$result" | grep -q 'panic via update' && \ + echo "PASS" || (echo "FAIL" && exit 1) - # Test call to fail with failed unwrap. - # Ignore failed dfx command output (so the test continues) and check the logs to contain the message. - - dfx canister call canister_logs failed_unwrap - dfx canister logs canister_logs \ - | grep 'Result::unwrap()' && echo 'PASS' + @echo "=== Test 8: memory out of bounds call is recorded in logs ===" + @icp canister call backend memory_oob '()' 2>/dev/null; \ + result=$$(icp canister logs backend) && \ + echo "$$result" && \ + echo "$$result" | grep -q 'stable memory out of bounds' && \ + echo "PASS" || (echo "FAIL" && exit 1) - # Test timer trap. - # The timer is setup to trap every 5 seconds, so this test has to be called - # at least 5 seconds after the start to record the trap log message. - sleep 5 - dfx canister logs canister_logs \ - | grep 'timer trap' && echo 'PASS' + @echo "=== Test 9: failed unwrap call is recorded in logs ===" + @icp canister call backend failed_unwrap '()' 2>/dev/null; \ + result=$$(icp canister logs backend) && \ + echo "$$result" && \ + echo "$$result" | grep -q "Result::unwrap()" && \ + echo "PASS" || (echo "FAIL" && exit 1) - # Test raw_rand. - dfx canister call canister_logs raw_rand - dfx canister logs canister_logs \ - | grep 'ic.raw_rand() call succeeded' && echo 'PASS' + @echo "=== Test 10: Polling for timer trap (up to 60s) ===" + @secs=0; \ + while [ $$secs -lt 60 ]; do \ + result=$$(icp canister logs backend); \ + echo "$$result"; \ + echo "$$result" | grep -q 'timer trap' && echo "PASS" && exit 0; \ + sleep 3; secs=$$((secs + 3)); \ + done; \ + echo "FAIL: timer trap not recorded within 60s"; exit 1 -.PHONY: clean -.SILENT: clean -clean: - rm -fr .dfx + @echo "=== Test 11: raw_rand call is recorded in logs ===" + @icp canister call backend raw_rand '()' && \ + result=$$(icp canister logs backend) && \ + echo "$$result" && \ + echo "$$result" | grep -q 'ic.raw_rand() call succeeded' && \ + echo "PASS" || (echo "FAIL" && exit 1) diff --git a/rust/canister_logs/README.md b/rust/canister_logs/README.md index 7e4cba402..6430f1b41 100644 --- a/rust/canister_logs/README.md +++ b/rust/canister_logs/README.md @@ -1,157 +1,85 @@ # Canister logs -This sample project demonstrates a basic logging and error handling system for a canister deployed on the Internet Computer. The `canister_logs` project showcases how to utilize logging for debugging and monitoring canister operations. It also demonstrates the use of timers and error handling through traps. +This example demonstrates canister logging and error handling on the Internet Computer. It shows how to use `ic_cdk::print` and `ic_cdk::println!` for diagnostic output, how traps, panics, and memory errors are automatically captured in the canister log, and how periodic timers generate log entries. -The `canister_logs` canister is designed to periodically log messages and simulate errors using traps. It provides methods to print messages, trigger traps, and handle memory out-of-bounds errors. The project includes a script to continuously poll and display logs, making it easier to monitor canister activity in real-time. +The canister exposes methods to print messages, trigger explicit traps, cause panics, simulate stable-memory out-of-bounds errors, and call `raw_rand`. A key behavioral distinction is demonstrated: log messages from **update calls and replicated queries** are recorded in the canister log, while messages from **non-replicated query calls** are not. -## Prerequisites +See also the [Motoko version](../../motoko/canister_logs). -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. -- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +## Build and deploy from the command line -## Deploying from ICP Ninja +### Prerequisites -When viewing this project in ICP Ninja, you can deploy it directly to the mainnet for free by clicking "Run" in the upper right corner. Open this project in ICP Ninja: +- Node.js +- icp-cli: `npm install -g @icp-sdk/icp-cli @icp-sdk/ic-wasm` -[![](https://icp.ninja/assets/open.svg)](https://icp.ninja/i?g=https://github.com/dfinity/examples/rust/canister_logs) +### Install +```bash +git clone https://github.com/dfinity/examples +cd examples/rust/canister_logs +``` -## Build and deploy from the command-line - -### 1. [Download and install the IC SDK.](https://internetcomputer.org/docs/building-apps/getting-started/install) - -### 2. Download your project from ICP Ninja using the 'Download files' button on the upper left corner, or [clone the GitHub examples repository.](https://github.com/dfinity/examples/) - -### 3. Navigate into the project's directory. - -### 4. Setup project environment - -Navigate into the folder containing the project's files and start a local instance of the replica with the commandss: +### Deploy and test -```shell -dfx start --clean +```bash +icp network start -d +icp deploy +make test +icp network stop ``` -You will need to have 3 terminal windows: +### Check canister logs -- Terminal A: Running a `dfx` instance and separating its output from anything else. -- Terminal B: Deploying a canister and seeing its output. -- Terminal C: Reading logs interactively. +After deploying, inspect logs directly: -```shell -# Terminal A -- for running DFX and separating its output from anything else. -cd examples/rust/canister_logs - -# Terminal B -- for deploying the canister and calling its methods. -cd examples/rust/canister_logs - -# Terminal C -- for polling logs. -cd examples/rust/canister_logs +```bash +icp canister logs backend ``` -### 5. Deploy the canister +Expect to see periodic timer trap entries every 5 seconds: -```shell -# Terminal B -dfx deploy ``` - -### 6. Check canister logs - -Expect to see logs from timer traps. - -```shell -# Terminal B -dfx canister logs CanisterLogs -[0. 2024-05-23T08:32:26.203980235Z]: right before timer trap -[1. 2024-05-23T08:32:26.203980235Z]: [TRAP]: timer trap -[2. 2024-05-23T08:32:31.836721763Z]: right before timer trap -[3. 2024-05-23T08:32:31.836721763Z]: [TRAP]: timer trap +[0. 2024-05-23T08:32:26Z]: right before timer trap +[1. 2024-05-23T08:32:26Z]: [TRAP]: timer trap +[2. 2024-05-23T08:32:31Z]: right before timer trap +[3. 2024-05-23T08:32:31Z]: [TRAP]: timer trap ``` -### 7. Call `print` method and check the logs - -```shell -# Terminal B -dfx canister call CanisterLogs print hi -() - -# Expect to see new log entry. -dfx canister logs CanisterLogs -... -[8. 2024-05-23T08:32:46.598972616Z]: right before timer trap -[9. 2024-05-23T08:32:46.598972616Z]: [TRAP]: timer trap -[10. 2024-05-23T08:32:48.713755238Z]: hi -[11. 2024-05-23T08:32:51.623988313Z]: right before timer trap -[12. 2024-05-23T08:32:51.623988313Z]: [TRAP]: timer trap -... -``` +To follow logs in real time: -### 8. Start constantly polling logs +```bash +icp canister logs --follow backend +``` -In order not to call `dfx canister logs CanisterLogs` after every canister call in a separate terminal window/pane C start a script that will constantly poll logs: +### Call canister methods manually -```shell -# Terminal C -$ ./poll_logs.sh -... -[8. 2024-05-23T08:32:46.598972616Z]: right before timer trap -[9. 2024-05-23T08:32:46.598972616Z]: [TRAP]: timer trap -[10. 2024-05-23T08:32:48.713755238Z]: hi -[11. 2024-05-23T08:32:51.623988313Z]: right before timer trap -[12. 2024-05-23T08:32:51.623988313Z]: [TRAP]: timer trap -... -``` +```bash +# Print a message (update call — recorded in logs) +icp canister call backend print '("hello!")' -### 9. Call `print`, `trap` and other canister methods +# Print via replicated query (recorded in logs) +icp canister call --update backend print_query '("hello from query!")' -```shell -# Terminal B -dfx canister call CanisterLogs print hi! -() +# Print via non-replicated query (NOT recorded in logs) +icp canister call --query backend print_query '("this will not appear in logs")' -dfx canister call CanisterLogs print hello! -() +# Trigger an explicit trap (error returned, message recorded in logs) +icp canister call backend trap '("oops!")' -dfx canister call CanisterLogs print yey! -() +# Trigger a Rust panic (error returned, message recorded in logs) +icp canister call backend panic '("something went wrong")' -dfx canister call CanisterLogs trap oops! -Error: Failed update call. -Caused by: Failed update call. - The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: oops!, error code None +# Trigger a stable-memory out-of-bounds error (recorded in logs) +icp canister call backend memory_oob '()' -dfx canister call CanisterLogs memory_oob -Error: Failed update call. -Caused by: Failed update call. - The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: StableMemory range out of bounds, error code None +# Trigger a failed unwrap (recorded in logs) +icp canister call backend failed_unwrap '()' +# Call raw_rand (result returned, success message recorded in logs) +icp canister call backend raw_rand '()' ``` -Observe recorded logs that might look similar to this: - -```shell -# Terminal C -... -[19. 2024-05-23T08:33:11.319493785Z]: right before timer trap -[20. 2024-05-23T08:33:11.319493785Z]: [TRAP]: timer trap -[21. 2024-05-23T08:33:14.229855179Z]: hi! -[22. 2024-05-23T08:33:16.413512126Z]: right before timer trap -[23. 2024-05-23T08:33:16.413512126Z]: [TRAP]: timer trap -[24. 2024-05-23T08:33:18.622686552Z]: hello! -[25. 2024-05-23T08:33:21.519088681Z]: right before timer trap -[26. 2024-05-23T08:33:21.519088681Z]: [TRAP]: timer trap -[27. 2024-05-23T08:33:22.96101893Z]: yey! -[28. 2024-05-23T08:33:26.601860526Z]: right before timer trap -[29. 2024-05-23T08:33:26.601860526Z]: [TRAP]: timer trap -[30. 2024-05-23T08:33:28.039227914Z]: right before trap -[31. 2024-05-23T08:33:28.039227914Z]: [TRAP]: oops! -[32. 2024-05-23T08:33:31.634215234Z]: right before timer trap -[33. 2024-05-23T08:33:31.634215234Z]: [TRAP]: timer trap -[34. 2024-05-23T08:33:35.96761902Z]: right before memory out of bounds -[35. 2024-05-23T08:33:35.96761902Z]: [TRAP]: StableMemory range out of bounds -[36. 2024-05-23T08:33:36.712223153Z]: right before timer trap -[37. 2024-05-23T08:33:36.712223153Z]: [TRAP]: timer trap -... +## Security considerations and best practices -``` +When building production canisters, review the [ICP security best practices](https://docs.internetcomputer.org/guides/security/overview). diff --git a/rust/canister_logs/backend/Cargo.toml b/rust/canister_logs/backend/Cargo.toml new file mode 100644 index 000000000..6230106aa --- /dev/null +++ b/rust/canister_logs/backend/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "backend" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] +path = "lib.rs" + +[dependencies] +candid = "0.10" +ic-cdk = "0.20" +ic-cdk-management-canister = "0.1.1" +ic-cdk-timers = "1.0" diff --git a/rust/canister_logs/src/lib.rs b/rust/canister_logs/backend/lib.rs similarity index 92% rename from rust/canister_logs/src/lib.rs rename to rust/canister_logs/backend/lib.rs index c2e04d957..d8d9119eb 100644 --- a/rust/canister_logs/src/lib.rs +++ b/rust/canister_logs/backend/lib.rs @@ -1,6 +1,5 @@ -use ic_cdk::{ - api::management_canister::main::raw_rand as ic00_raw_rand, init, post_upgrade, query, update, -}; +use ic_cdk::{init, post_upgrade, query, update}; +use ic_cdk_management_canister::raw_rand as ic00_raw_rand; use std::time::Duration; const TIMER_INTERVAL_SEC: u64 = 5; @@ -68,7 +67,7 @@ fn failed_unwrap() { async fn raw_rand() -> Vec { ic_cdk::println!("pre ic.raw_rand() call"); match ic00_raw_rand().await { - Ok((bytes,)) => { + Ok(bytes) => { ic_cdk::println!("ic.raw_rand() call succeeded"); bytes } diff --git a/rust/canister_logs/canister_logs.did b/rust/canister_logs/canister_logs.did deleted file mode 100644 index 167e4e747..000000000 --- a/rust/canister_logs/canister_logs.did +++ /dev/null @@ -1,10 +0,0 @@ -service : { - "print" : (text) -> (); - "print_query" : (text) -> () query; - "trap" : (text) -> (); - "trap_query" : (text) -> () query; - "panic" : (text) -> (); - "memory_oob" : () -> (); - "failed_unwrap" : () -> (); - "raw_rand" : () -> (blob); -}; diff --git a/rust/canister_logs/dfx.json b/rust/canister_logs/dfx.json deleted file mode 100644 index eaedae813..000000000 --- a/rust/canister_logs/dfx.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "canisters": { - "canister_logs": { - "candid": "canister_logs.did", - "package": "canister_logs", - "type": "rust" - } - }, - "version": 1 -} diff --git a/rust/canister_logs/icp.yaml b/rust/canister_logs/icp.yaml new file mode 100644 index 000000000..df5c7edaa --- /dev/null +++ b/rust/canister_logs/icp.yaml @@ -0,0 +1,8 @@ +networks: + - name: local + mode: managed + +canisters: + - name: backend + recipe: + type: "@dfinity/rust@v3.3.0" diff --git a/rust/canister_logs/package-lock.json b/rust/canister_logs/package-lock.json deleted file mode 100644 index 5f7a67cc6..000000000 --- a/rust/canister_logs/package-lock.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "canister_logs", - "lockfileVersion": 3, - "requires": true, - "packages": {} - } - \ No newline at end of file diff --git a/rust/canister_logs/poll_logs.sh b/rust/canister_logs/poll_logs.sh deleted file mode 100755 index 7c839ada3..000000000 --- a/rust/canister_logs/poll_logs.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -# Function to fetch logs and filter out new lines -fetch_and_filter_logs() { - # Fetch logs - new_logs=$(dfx canister logs canister_logs) - - # Compare with previous logs to find new ones - while IFS= read -r line; do - if [[ ! "${previous_logs[*]}" =~ "$line" ]]; then - echo "$line" - fi - done <<< "$new_logs" - - # Update previous logs - previous_logs=("$new_logs") -} - -# Initial fetch and filter -fetch_and_filter_logs - -# Infinite loop to continuously fetch and filter logs -while true; do - fetch_and_filter_logs - sleep 1 -done diff --git a/rust/canister_logs/rust-toolchain.toml b/rust/canister_logs/rust-toolchain.toml index f8bb13962..990104f05 100644 --- a/rust/canister_logs/rust-toolchain.toml +++ b/rust/canister_logs/rust-toolchain.toml @@ -1,4 +1,2 @@ [toolchain] -channel = "1.74" targets = ["wasm32-unknown-unknown"] -components = ["rustfmt", "clippy"]