codeharness 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1389 -542
- package/package.json +3 -1
- package/patches/dev/enforcement.md +10 -0
- package/patches/infra/dockerfile-rules.md +62 -0
- package/patches/observability/AGENTS.md +20 -0
- package/patches/observability/rust-catch-without-tracing.rs +65 -0
- package/patches/observability/rust-catch-without-tracing.yaml +19 -0
- package/patches/observability/rust-error-path-no-tracing.rs +79 -0
- package/patches/observability/rust-error-path-no-tracing.yaml +62 -0
- package/patches/observability/rust-function-no-tracing.rs +119 -0
- package/patches/observability/rust-function-no-tracing.yaml +282 -0
- package/patches/review/enforcement.md +9 -0
- package/patches/verify/story-verification.md +23 -0
- package/templates/Dockerfile.verify.generic +27 -0
- package/templates/Dockerfile.verify.rust +39 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeharness",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI for codeharness — makes autonomous coding agents produce software that actually works",
|
|
6
6
|
"bin": {
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
"bin",
|
|
12
12
|
"patches",
|
|
13
13
|
"templates/Dockerfile.verify",
|
|
14
|
+
"templates/Dockerfile.verify.rust",
|
|
15
|
+
"templates/Dockerfile.verify.generic",
|
|
14
16
|
"ralph/**/*.sh",
|
|
15
17
|
"ralph/AGENTS.md"
|
|
16
18
|
],
|
|
@@ -18,6 +18,8 @@ Before writing code, read the relevant `AGENTS.md` file for the module being cha
|
|
|
18
18
|
|
|
19
19
|
### Observability
|
|
20
20
|
|
|
21
|
+
Run `semgrep scan --config patches/observability/` before committing and fix any gaps.
|
|
22
|
+
|
|
21
23
|
After running tests, verify telemetry is flowing:
|
|
22
24
|
- Query VictoriaLogs to confirm log events from test runs
|
|
23
25
|
- If observability is configured, traces should be visible for CLI operations
|
|
@@ -41,3 +43,11 @@ Write code that can be verified from the outside. Ask yourself:
|
|
|
41
43
|
- Would a verifier with NO source access be able to tell if this works?
|
|
42
44
|
|
|
43
45
|
If the answer is "no", the feature has a testability gap — fix the CLI/docs, not the verification process.
|
|
46
|
+
|
|
47
|
+
### Dockerfile Maintenance
|
|
48
|
+
|
|
49
|
+
If this story adds a new runtime dependency, check whether the Dockerfile needs updating:
|
|
50
|
+
- New system package required at runtime (e.g., `libssl`, `ffmpeg`) — add to `apt-get install` line
|
|
51
|
+
- New binary expected on PATH — add install step to Dockerfile
|
|
52
|
+
- New Python package needed — add to `pip install` or `requirements.txt` COPY
|
|
53
|
+
- Verify the updated Dockerfile still passes `validateDockerfile()` with zero gaps
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Dockerfile Rules
|
|
2
|
+
|
|
3
|
+
Required elements for verification Dockerfiles. The `validateDockerfile()` function checks all six categories below. Gaps are reported through the audit infrastructure dimension.
|
|
4
|
+
|
|
5
|
+
## Required Elements
|
|
6
|
+
|
|
7
|
+
### 1. Pinned FROM Image
|
|
8
|
+
|
|
9
|
+
Base images must use a specific version tag or digest. Using `:latest` or omitting a tag results in non-reproducible builds.
|
|
10
|
+
|
|
11
|
+
- **Pass:** `FROM node:22-slim`, `FROM python:3.12-slim`, `FROM node@sha256:abc123`
|
|
12
|
+
- **Fail:** `FROM node:latest`, `FROM node`
|
|
13
|
+
|
|
14
|
+
### 2. Project Binary on PATH
|
|
15
|
+
|
|
16
|
+
The container must install the project binary so it is available on PATH. This prevents "container missing binary" failures.
|
|
17
|
+
|
|
18
|
+
- **Patterns:** `npm install -g`, `pip install`, `COPY --from=builder`
|
|
19
|
+
|
|
20
|
+
### 3. Verification Tools
|
|
21
|
+
|
|
22
|
+
Containers must include tools needed for health checks and diagnostics: `curl`, `jq`.
|
|
23
|
+
|
|
24
|
+
- **Install via:** `apt-get install -y curl jq` or `apk add --no-cache curl jq`
|
|
25
|
+
|
|
26
|
+
### 4. No Source Code COPY
|
|
27
|
+
|
|
28
|
+
Containers should use build artifacts, not raw source. Copying source directories inflates image size and leaks code.
|
|
29
|
+
|
|
30
|
+
- **Fail patterns:** `COPY src/`, `COPY lib/`, `COPY test/`
|
|
31
|
+
- **Pass:** `COPY --from=builder /app/dist /app/dist`, `COPY dist/ /app/dist/`
|
|
32
|
+
|
|
33
|
+
### 5. Non-root USER
|
|
34
|
+
|
|
35
|
+
Containers must not run as root. Include a `USER` instruction with a non-root user.
|
|
36
|
+
|
|
37
|
+
- **Pass:** `USER node`, `USER appuser`, `USER 1001`
|
|
38
|
+
- **Fail:** no `USER` instruction, or only `USER root`
|
|
39
|
+
|
|
40
|
+
### 6. Cache Cleanup
|
|
41
|
+
|
|
42
|
+
Package manager caches must be cleaned to reduce image size.
|
|
43
|
+
|
|
44
|
+
- **Patterns:** `rm -rf /var/lib/apt/lists/*`, `npm cache clean --force`, `pip cache purge`
|
|
45
|
+
|
|
46
|
+
## Project-Type-Specific Notes
|
|
47
|
+
|
|
48
|
+
### Node.js
|
|
49
|
+
|
|
50
|
+
- Use `npm install -g <package>` to put the binary on PATH
|
|
51
|
+
- Use `npm cache clean --force` after install
|
|
52
|
+
- Prefer `node:22-slim` or `node:22-alpine` base images
|
|
53
|
+
|
|
54
|
+
### Python
|
|
55
|
+
|
|
56
|
+
- Use `pip install --no-cache-dir <package>` or `pip cache purge`
|
|
57
|
+
- Prefer `python:3.12-slim` base images
|
|
58
|
+
|
|
59
|
+
### Plugin (Claude Code)
|
|
60
|
+
|
|
61
|
+
- Plugin containers typically use Node.js base
|
|
62
|
+
- Ensure `codeharness` binary is installed globally via `npm install -g`
|
|
@@ -4,20 +4,40 @@ Standalone Semgrep YAML rules for static analysis of observability gaps. Each `.
|
|
|
4
4
|
|
|
5
5
|
## Rules
|
|
6
6
|
|
|
7
|
+
### JavaScript / TypeScript
|
|
8
|
+
|
|
7
9
|
| File | Purpose | Severity |
|
|
8
10
|
|------|---------|----------|
|
|
9
11
|
| catch-without-logging.yaml | Detects catch blocks without error/warn logging | WARNING |
|
|
10
12
|
| function-no-debug-log.yaml | Detects functions without debug/info logging | INFO |
|
|
11
13
|
| error-path-no-log.yaml | Detects error paths (throw/return err) without preceding log | WARNING |
|
|
12
14
|
|
|
15
|
+
### Rust
|
|
16
|
+
|
|
17
|
+
| File | Purpose | Severity |
|
|
18
|
+
|------|---------|----------|
|
|
19
|
+
| rust-function-no-tracing.yaml | Detects Rust functions without tracing instrumentation | INFO |
|
|
20
|
+
| rust-catch-without-tracing.yaml | Detects Rust error match arms without tracing | WARNING |
|
|
21
|
+
| rust-error-path-no-tracing.yaml | Detects Rust error-path closures (map_err/unwrap_or_else) without tracing | WARNING |
|
|
22
|
+
|
|
13
23
|
## Test Fixtures
|
|
14
24
|
|
|
25
|
+
### JavaScript / TypeScript
|
|
26
|
+
|
|
15
27
|
| File | Purpose |
|
|
16
28
|
|------|---------|
|
|
17
29
|
| catch-without-logging.ts | Test cases for catch-without-logging rule (annotated with `// ruleid:` / `// ok:`) |
|
|
18
30
|
| function-no-debug-log.ts | Test cases for function-no-debug-log rule |
|
|
19
31
|
| error-path-no-log.ts | Test cases for error-path-no-log rule |
|
|
20
32
|
|
|
33
|
+
### Rust
|
|
34
|
+
|
|
35
|
+
| File | Purpose |
|
|
36
|
+
|------|---------|
|
|
37
|
+
| rust-function-no-tracing.rs | Test cases for rust-function-no-tracing rule |
|
|
38
|
+
| rust-catch-without-tracing.rs | Test cases for rust-catch-without-tracing rule |
|
|
39
|
+
| rust-error-path-no-tracing.rs | Test cases for rust-error-path-no-tracing rule |
|
|
40
|
+
|
|
21
41
|
## Testing
|
|
22
42
|
|
|
23
43
|
Run `semgrep --test patches/observability/` to execute all test fixtures against their rules.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Test cases for rust-catch-without-tracing Semgrep rule
|
|
2
|
+
|
|
3
|
+
fn bad_match_no_logging(result: Result<i32, String>) {
|
|
4
|
+
match result {
|
|
5
|
+
Ok(val) => println!("{}", val),
|
|
6
|
+
// ruleid: rust-catch-without-tracing
|
|
7
|
+
Err(e) => {
|
|
8
|
+
cleanup();
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
fn bad_match_wildcard(result: Result<i32, String>) {
|
|
14
|
+
match result {
|
|
15
|
+
Ok(val) => println!("{}", val),
|
|
16
|
+
// ruleid: rust-catch-without-tracing
|
|
17
|
+
Err(_) => {
|
|
18
|
+
fallback();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
fn good_match_with_tracing_error(result: Result<i32, String>) {
|
|
24
|
+
match result {
|
|
25
|
+
Ok(val) => println!("{}", val),
|
|
26
|
+
// ok: rust-catch-without-tracing
|
|
27
|
+
Err(e) => {
|
|
28
|
+
tracing::error!("operation failed: {}", e);
|
|
29
|
+
cleanup();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fn good_match_with_tracing_warn(result: Result<i32, String>) {
|
|
35
|
+
match result {
|
|
36
|
+
Ok(val) => println!("{}", val),
|
|
37
|
+
// ok: rust-catch-without-tracing
|
|
38
|
+
Err(e) => {
|
|
39
|
+
tracing::warn!("operation failed: {}", e);
|
|
40
|
+
cleanup();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
fn good_match_with_bare_error(result: Result<i32, String>) {
|
|
46
|
+
match result {
|
|
47
|
+
Ok(val) => println!("{}", val),
|
|
48
|
+
// ok: rust-catch-without-tracing
|
|
49
|
+
Err(e) => {
|
|
50
|
+
error!("operation failed: {}", e);
|
|
51
|
+
cleanup();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
fn good_match_with_bare_warn(result: Result<i32, String>) {
|
|
57
|
+
match result {
|
|
58
|
+
Ok(val) => println!("{}", val),
|
|
59
|
+
// ok: rust-catch-without-tracing
|
|
60
|
+
Err(e) => {
|
|
61
|
+
warn!("operation failed: {}", e);
|
|
62
|
+
cleanup();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
rules:
|
|
2
|
+
- id: rust-catch-without-tracing
|
|
3
|
+
patterns:
|
|
4
|
+
- pattern: |
|
|
5
|
+
match $X { Err($E) => { ... } }
|
|
6
|
+
- pattern-not: |
|
|
7
|
+
match $X { Err($E) => { ... tracing::error!(...); ... } }
|
|
8
|
+
- pattern-not: |
|
|
9
|
+
match $X { Err($E) => { ... tracing::warn!(...); ... } }
|
|
10
|
+
- pattern-not: |
|
|
11
|
+
match $X { Err($E) => { ... error!(...); ... } }
|
|
12
|
+
- pattern-not: |
|
|
13
|
+
match $X { Err($E) => { ... warn!(...); ... } }
|
|
14
|
+
message: "Rust error match arm without tracing — observability gap"
|
|
15
|
+
languages: [rust]
|
|
16
|
+
severity: WARNING
|
|
17
|
+
metadata:
|
|
18
|
+
category: observability
|
|
19
|
+
cwe: "CWE-778: Insufficient Logging"
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Test cases for rust-error-path-no-tracing Semgrep rule
|
|
2
|
+
|
|
3
|
+
fn bad_map_err() {
|
|
4
|
+
// ruleid: rust-error-path-no-tracing
|
|
5
|
+
let result = some_operation().map_err(|e| {
|
|
6
|
+
CustomError::new(e)
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
fn bad_unwrap_or_else() {
|
|
11
|
+
// ruleid: rust-error-path-no-tracing
|
|
12
|
+
let value = some_operation().unwrap_or_else(|e| {
|
|
13
|
+
default_value()
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
fn good_map_err_with_tracing_error() {
|
|
18
|
+
// ok: rust-error-path-no-tracing
|
|
19
|
+
let result = some_operation().map_err(|e| {
|
|
20
|
+
tracing::error!("operation failed: {}", e);
|
|
21
|
+
CustomError::new(e)
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
fn good_map_err_with_tracing_warn() {
|
|
26
|
+
// ok: rust-error-path-no-tracing
|
|
27
|
+
let result = some_operation().map_err(|e| {
|
|
28
|
+
tracing::warn!("operation failed: {}", e);
|
|
29
|
+
CustomError::new(e)
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
fn good_map_err_with_bare_error() {
|
|
34
|
+
// ok: rust-error-path-no-tracing
|
|
35
|
+
let result = some_operation().map_err(|e| {
|
|
36
|
+
error!("operation failed: {}", e);
|
|
37
|
+
CustomError::new(e)
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
fn good_map_err_with_bare_warn() {
|
|
42
|
+
// ok: rust-error-path-no-tracing
|
|
43
|
+
let result = some_operation().map_err(|e| {
|
|
44
|
+
warn!("operation failed: {}", e);
|
|
45
|
+
CustomError::new(e)
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
fn good_unwrap_or_else_with_tracing_error() {
|
|
50
|
+
// ok: rust-error-path-no-tracing
|
|
51
|
+
let value = some_operation().unwrap_or_else(|e| {
|
|
52
|
+
tracing::error!("falling back: {}", e);
|
|
53
|
+
default_value()
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
fn good_unwrap_or_else_with_tracing_warn() {
|
|
58
|
+
// ok: rust-error-path-no-tracing
|
|
59
|
+
let value = some_operation().unwrap_or_else(|e| {
|
|
60
|
+
tracing::warn!("falling back: {}", e);
|
|
61
|
+
default_value()
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
fn good_unwrap_or_else_with_bare_error() {
|
|
66
|
+
// ok: rust-error-path-no-tracing
|
|
67
|
+
let value = some_operation().unwrap_or_else(|e| {
|
|
68
|
+
error!("falling back: {}", e);
|
|
69
|
+
default_value()
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
fn good_unwrap_or_else_with_bare_warn() {
|
|
74
|
+
// ok: rust-error-path-no-tracing
|
|
75
|
+
let value = some_operation().unwrap_or_else(|e| {
|
|
76
|
+
warn!("falling back: {}", e);
|
|
77
|
+
default_value()
|
|
78
|
+
});
|
|
79
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
rules:
|
|
2
|
+
- id: rust-error-path-no-tracing
|
|
3
|
+
patterns:
|
|
4
|
+
- pattern-either:
|
|
5
|
+
- pattern: |
|
|
6
|
+
$X.map_err(|$E| { ... })
|
|
7
|
+
- pattern: |
|
|
8
|
+
$X.unwrap_or_else(|$E| { ... })
|
|
9
|
+
- pattern-not: |
|
|
10
|
+
$X.map_err(|$E| {
|
|
11
|
+
...
|
|
12
|
+
tracing::error!(...);
|
|
13
|
+
...
|
|
14
|
+
})
|
|
15
|
+
- pattern-not: |
|
|
16
|
+
$X.map_err(|$E| {
|
|
17
|
+
...
|
|
18
|
+
tracing::warn!(...);
|
|
19
|
+
...
|
|
20
|
+
})
|
|
21
|
+
- pattern-not: |
|
|
22
|
+
$X.map_err(|$E| {
|
|
23
|
+
...
|
|
24
|
+
error!(...);
|
|
25
|
+
...
|
|
26
|
+
})
|
|
27
|
+
- pattern-not: |
|
|
28
|
+
$X.map_err(|$E| {
|
|
29
|
+
...
|
|
30
|
+
warn!(...);
|
|
31
|
+
...
|
|
32
|
+
})
|
|
33
|
+
- pattern-not: |
|
|
34
|
+
$X.unwrap_or_else(|$E| {
|
|
35
|
+
...
|
|
36
|
+
tracing::error!(...);
|
|
37
|
+
...
|
|
38
|
+
})
|
|
39
|
+
- pattern-not: |
|
|
40
|
+
$X.unwrap_or_else(|$E| {
|
|
41
|
+
...
|
|
42
|
+
tracing::warn!(...);
|
|
43
|
+
...
|
|
44
|
+
})
|
|
45
|
+
- pattern-not: |
|
|
46
|
+
$X.unwrap_or_else(|$E| {
|
|
47
|
+
...
|
|
48
|
+
error!(...);
|
|
49
|
+
...
|
|
50
|
+
})
|
|
51
|
+
- pattern-not: |
|
|
52
|
+
$X.unwrap_or_else(|$E| {
|
|
53
|
+
...
|
|
54
|
+
warn!(...);
|
|
55
|
+
...
|
|
56
|
+
})
|
|
57
|
+
message: "Rust error-path closure without tracing — observability gap"
|
|
58
|
+
languages: [rust]
|
|
59
|
+
severity: WARNING
|
|
60
|
+
metadata:
|
|
61
|
+
category: observability
|
|
62
|
+
cwe: "CWE-778: Insufficient Logging"
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// Test cases for rust-function-no-tracing Semgrep rule
|
|
2
|
+
|
|
3
|
+
// ruleid: rust-function-no-tracing
|
|
4
|
+
fn process_data(input: &str) -> String {
|
|
5
|
+
input.trim().to_string()
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// ruleid: rust-function-no-tracing
|
|
9
|
+
pub fn handle_request(req: Request) -> Response {
|
|
10
|
+
let result = compute(req);
|
|
11
|
+
result
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// ruleid: rust-function-no-tracing
|
|
15
|
+
async fn fetch_data(url: &str) -> Result<String, Error> {
|
|
16
|
+
let resp = client.get(url).send().await?;
|
|
17
|
+
resp.text().await
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ruleid: rust-function-no-tracing
|
|
21
|
+
pub async fn serve(addr: &str) -> Result<(), Error> {
|
|
22
|
+
let listener = TcpListener::bind(addr).await?;
|
|
23
|
+
loop {
|
|
24
|
+
let (stream, _) = listener.accept().await?;
|
|
25
|
+
handle(stream).await;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ok: rust-function-no-tracing
|
|
30
|
+
fn process_with_debug(input: &str) -> String {
|
|
31
|
+
tracing::debug!("processing input");
|
|
32
|
+
input.trim().to_string()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ok: rust-function-no-tracing
|
|
36
|
+
pub fn handle_with_info(req: Request) -> Response {
|
|
37
|
+
tracing::info!("handling request");
|
|
38
|
+
let result = compute(req);
|
|
39
|
+
result
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ok: rust-function-no-tracing
|
|
43
|
+
async fn fetch_with_warn(url: &str) -> Result<String, Error> {
|
|
44
|
+
tracing::warn!("fetching data from {}", url);
|
|
45
|
+
let resp = client.get(url).send().await?;
|
|
46
|
+
resp.text().await
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ok: rust-function-no-tracing
|
|
50
|
+
pub async fn serve_with_error(addr: &str) -> Result<(), Error> {
|
|
51
|
+
tracing::error!("starting server on {}", addr);
|
|
52
|
+
let listener = TcpListener::bind(addr).await?;
|
|
53
|
+
loop {
|
|
54
|
+
let (stream, _) = listener.accept().await?;
|
|
55
|
+
handle(stream).await;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ok: rust-function-no-tracing
|
|
60
|
+
fn process_with_bare_debug(input: &str) -> String {
|
|
61
|
+
debug!("processing input");
|
|
62
|
+
input.trim().to_string()
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ok: rust-function-no-tracing
|
|
66
|
+
pub fn handle_with_bare_info(req: Request) -> Response {
|
|
67
|
+
info!("handling request");
|
|
68
|
+
let result = compute(req);
|
|
69
|
+
result
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ok: rust-function-no-tracing
|
|
73
|
+
async fn fetch_with_bare_error(url: &str) -> Result<String, Error> {
|
|
74
|
+
error!("fetching data from {}", url);
|
|
75
|
+
let resp = client.get(url).send().await?;
|
|
76
|
+
resp.text().await
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ok: rust-function-no-tracing
|
|
80
|
+
fn traced_with_namespaced_trace(input: &str) -> String {
|
|
81
|
+
tracing::trace!("trace-level log");
|
|
82
|
+
input.trim().to_string()
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ok: rust-function-no-tracing
|
|
86
|
+
fn traced_with_bare_trace(input: &str) -> String {
|
|
87
|
+
trace!("trace-level log");
|
|
88
|
+
input.trim().to_string()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// ok: rust-function-no-tracing
|
|
92
|
+
#[tracing::instrument]
|
|
93
|
+
fn instrumented_function(input: &str) -> String {
|
|
94
|
+
input.trim().to_string()
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ok: rust-function-no-tracing
|
|
98
|
+
#[instrument]
|
|
99
|
+
pub fn instrumented_pub_function(req: Request) -> Response {
|
|
100
|
+
let result = compute(req);
|
|
101
|
+
result
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ok: rust-function-no-tracing
|
|
105
|
+
#[tracing::instrument]
|
|
106
|
+
async fn instrumented_async(url: &str) -> Result<String, Error> {
|
|
107
|
+
let resp = client.get(url).send().await?;
|
|
108
|
+
resp.text().await
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ok: rust-function-no-tracing
|
|
112
|
+
#[instrument]
|
|
113
|
+
pub async fn instrumented_pub_async(addr: &str) -> Result<(), Error> {
|
|
114
|
+
let listener = TcpListener::bind(addr).await?;
|
|
115
|
+
loop {
|
|
116
|
+
let (stream, _) = listener.accept().await?;
|
|
117
|
+
handle(stream).await;
|
|
118
|
+
}
|
|
119
|
+
}
|