Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Linkly

BSecurity

Observability in iii isn't something you bolt onto each service. Every cross-worker call already flows through the engine, so the engine can trace and log the whole system end to end. In this chapter you open the console to see that, then, if you want, read the same data directly from the engine.

18,691 stars
0 votes
0 copies
0 views
Added 9/20/2026
developmentshellbashnodebackend

Works with

cli

Security Analysis

B88/100
criticalExfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study

Scanned 9/20/2026

Install to Claude Code

$npx -y skills add iii-hq/iii --skill linkly --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Linkly?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Linkly
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/iii-hq-linkly-3f381345/badge)](https://www.skillsdirectory.com/skills/iii-hq-linkly-3f381345)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
channels.mdx
<!-- generated by iii-skill-render. DO NOT EDIT (changes here are overwritten on the next render). Edit docs/next/tutorials/linkly/observability.mdx. -->

# Ch. 2: Observe everything


Observability in iii isn't something you bolt onto each service. Every cross-worker call already
flows through the engine, so the engine can trace and log the whole system end to end. In this
chapter you open the console to see that, then, if you want, read the same data directly from the
engine.

## Open the console

The engine has been running since Chapter 1. Start the console, a browser UI for inspecting it:

```bash
iii console
```

Open it at [http://127.0.0.1:3113/traces](http://127.0.0.1:3113/traces). Every worker you added is
listed with the functions and triggers it registered. Navigate to the traces tab and run the below
command to watch the invocations stream live:

```bash
curl -s -X POST http://127.0.0.1:3111/links \
  -H 'Content-Type: application/json' -d '{"url":"https://iii.dev","code":"iii"}'
for n in $(seq 1 5); do curl -s -o /dev/null http://127.0.0.1:3111/s/iii; done
```

Click any redirect to see a full waterfall of timed spans crossing from `http` into `link` and
back:

![iii console Traces page showing redirect spans sorted by duration with the waterfall for a selected GET /s/:code trace](/next/tutorials/linkly/console-traces.png)

You didn't add a tracing library or thread a request ID between services to get this.
The engine injects `iii-observability` automatically, so it must not be declared in `config.yaml`
or `worker-compose.yaml`. Every request gets a trace and every `Logger` line is collected
automatically across workers. In iii, end-to-end observability is an inherent property of the
system.

<Info>
  **iii-observability emits OpenTelemetry.** Its traces, metrics, and logs are emitted as OTel, so
  you aren't locked into the console. You can point the worker at Honeycomb, Grafana, Datadog, or
  any other OTel-compatible backend. See the worker's configuration on
  [workers.iii.dev/workers/iii-observability](https://workers.iii.dev/workers/iii-observability);
  its settings are managed at runtime through the [configuration worker](/using-iii/configuration).
</Info>

For most teams the console (or your own OTel backend) is all you need day to day.

<Note>
  The rest of this chapter is an optional deep dive on how to read the same logs and traces directly
  from the engine. You can jump to [Ch. 3: Persist everything](/tutorials/linkly/persistence) if you
  prefer.
</Note>

## Read the logs

Create some traffic:

```bash
curl -s -X POST http://127.0.0.1:3111/links \
  -H 'Content-Type: application/json' -d '{"url":"https://iii.dev","code":"iii"}'
for n in $(seq 1 5); do curl -s -o /dev/null http://127.0.0.1:3111/s/iii; done
curl -s -o /dev/null http://127.0.0.1:3111/s/missing
```

Then check the logs:

```bash
iii trigger engine::logs::list limit=100 \
  | jq '.logs[]
      | select(.body == "link resolved")
      | { body,
          data: (.attributes | with_entries(select(.key | IN("trace_id","span_id","service.name") | not))),
          trace_id,
          service_name }'
```

<Info>
  The `jq` pipe filters the response down to the `link resolved` entries and keeps the parts that
  matter for this tutorial, try removing it to see all the information the iii engine can provide.
</Info>

```json
{
  "body": "link resolved",
  "data": {
    "log.data": {
      "code": "iii",
      "found": true
    }
  },
  "trace_id": "797d427e4d0c3491cfc45f0d40c4e1b1",
  "service_name": "iii-node"
}
```

`data` is exactly what you passed to `logger.info`; the engine stores those fields as individual log
attributes, so the `jq` above gathers everything except the OTel metadata keys. The `trace_id` ties
the log to the trace it came from, which is where you look next.

## Follow a redirect across workers

Everything that happens on a iii system has a trace. So the http requests have traces that cover the
full execution context of the request. Grab the most recent redirect's `trace_id` and walk the whole
request as a tree. Capturing the id into a shell variable keeps this a single paste:

```bash
trace_id=$(iii trigger engine::traces::list name="GET /s/:code" limit=1 | jq -r '.traces[0].trace_id')
iii trigger engine::traces::tree trace_id="$trace_id" | jq -r '
  def walk(depth):
    ("  " * depth // "") + .name + " (" + .service_name + ") "
      + (((.end_time_unix_nano - .start_time_unix_nano) / 1e6 * 1000 | round) / 1000 | tostring) + " ms",
    (.children[]? | walk(depth + 1));
  .roots[] | walk(0)
'
```

<Info>
  The `jq` pipe walks the nested `roots` tree, indenting each span by depth and printing its
  `service_name` and duration in milliseconds. You get the full path of one redirect, across two
  workers:
</Info>

```text
GET /s/:code (iii) 2.044 ms
  execute http::redirect (iii-node) 1.444 ms
    execute link::resolve (iii-node) 0.52 ms
```

This shows the redirect arriving through `/s/:code` via the `http` worker's Trigger, calling
`http::redirect` in `link`, which then calls `link::resolve` in the `link` worker via the engine.
The per-span timing shows where the request spends its time.

<Note>
  Worker spans export on a short delay, so a brand-new request's trace can be missing or look
  truncated for a second or two. If you encounter this wait a few seconds and try again.
</Note>

## Compare traces to find the slowest links

To compare many traces it's possible to filter, list, and sort them in one operation. Here are the
redirect traces sorted by duration, slowest first:

```bash
iii trigger engine::traces::list name="GET /s/:code" sort_by=duration_ms sort_order=desc limit=10 \
  | jq -r '.traces[]
      | select(.end_time_unix_nano != null)
      | "\(((.end_time_unix_nano - .start_time_unix_nano) / 1e6 * 1000 | round) / 1000) ms  \(.trace_id)"'
```

Each line pairs a duration with its `trace_id`, slowest first:

```text
2.044 ms  6b20e1fe001742c25bb7dc570b57fe42
1.700 ms  797d427e4d0c3491cfc45f0d40c4e1b1
```

The slowest redirects rise to the top; open any one's `trace_id` with `engine::traces::tree` to see
which hop is responsible.

## Conclusion

Linkly is now observable: the console shows every worker, trace, and log as it happens, and you can
read the same data from the engine with `iii trigger`. The links are still kept only in memory,
though, so restarting the engine clears them. Next, in
[Ch. 3: Persist everything](/tutorials/linkly/persistence), you move them into durable storage.

Attribution

iii-hqiii-hq
View sourceMore from iii-hq →
SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

281612 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2132 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →