Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions cli/azd/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,20 +279,31 @@ public reference, and downstream Kusto/LENS consumers drift out of sync. Verify

**1. Code**

- **Field** — define an `AttributeKey` in `cli/azd/internal/tracing/fields/fields.go` (this file
holds the field/key definitions; within the same package `features.go` holds feature-name
attribute values and `domains.go` the Azure host-domain table). Every field MUST set a
`Classification` (e.g. `SystemMetadata`, `OrganizationalIdentifiableInformation`,
`EndUserPseudonymizedInformation`; never emit `CustomerContent`) and a `Purpose`
(`FeatureInsight` / `BusinessInsight` / `PerformanceAndHealth`).
- **Field** — define an **exported, package-level** `AttributeKey` var in
`cli/azd/internal/tracing/fields/fields.go` (this file holds the field/key definitions; within the
same package `features.go` holds feature-name attribute values and `domains.go` the Azure
host-domain table). Every field MUST set a `Classification` (e.g. `SystemMetadata`,
`OrganizationalIdentifiableInformation`, `EndUserPseudonymizedInformation`; never emit
`CustomerContent`) and a `Purpose` (`FeatureInsight` / `BusinessInsight` /
`PerformanceAndHealth`); the classifier also reads the optional `Endpoint` and `IsMeasurement`
members.
- **Event** — define a constant in `cli/azd/internal/tracing/events/events.go` following the
`prefix.noun.verb` naming convention.
`prefix.noun.verb` value convention. It must be an exported string `const` whose Go identifier
contains `Event` (end it with `Prefix` for a prefix-match group) so the classifier
discovers it.
- **Emit** at the call site via `tracing.Start` (spans/events) plus `tracing.SetUsageAttributes`
or `span.SetAttributes` (attributes).
or `span.SetAttributes` (attributes). Always pass a `fields.AttributeKey` method
(e.g. `fields.MyKey.String(v)` / `.Bool(v)` / `.Int(v)`) — never a raw
`attribute.String("my.key", v)`. The GDPR classifier discovers fields by statically scanning
the `fields` package for exported `AttributeKey` vars; a raw literal key is invisible to it, so the
property reaches App Insights but its data-catalog row stays Unclassified / `Complete=false`. Enforced by
`TestNoRawTelemetryAttributes` (`cli/azd/cmd/telemetry_test.go`); dynamic
`ext.*` keys are the only sanctioned exception.
- **Hash user-derived values** with `fields.StringHashed` / `fields.StringSliceHashed`
(`cli/azd/internal/tracing/fields/key.go`). Hash anything that embeds a user-chosen name, path,
repo URL, or project / env / service / layer identifier (e.g. `exegraph.step.name`, `hooks.name`).
Emit raw only for fixed enums or compile-time literals.
Emit raw only for fixed enums or compile-time literals (the key itself must
still be a `fields.AttributeKey`, per **Emit** above).

**2. Documentation — keep all of these in sync**

Expand Down
5 changes: 2 additions & 3 deletions cli/azd/cmd/auth_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import (
"github.com/azure/azure-dev/cli/azd/pkg/tools/github"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"go.opentelemetry.io/otel/attribute"
)

// The parent of the login command.
Expand Down Expand Up @@ -378,11 +377,11 @@ func (la *loginAction) Run(ctx context.Context) (*actions.ActionResult, error) {
if !isServicePrincipalOrMI {
if _, err := la.authManager.LogInDetails(ctx); !errors.Is(err, auth.ErrNoCurrentUser) {
if err := la.authManager.CleanAllAuthCache(); err != nil {
tracing.SetUsageAttributes(attribute.String("auth.cache_clear_failed", "auth"))
tracing.SetUsageAttributes(fields.AuthCacheClearFailedKey.String("auth"))
return nil, fmt.Errorf("clearing auth cache: %w", err)
}
if err := la.accountSubManager.ClearSubscriptions(ctx); err != nil {
tracing.SetUsageAttributes(attribute.String("auth.cache_clear_failed", "subscriptions"))
tracing.SetUsageAttributes(fields.AuthCacheClearFailedKey.String("subscriptions"))
return nil, fmt.Errorf("clearing subscriptions cache: %w", err)
}
}
Expand Down
Loading
Loading