Guidance for AI agents working in the Mocha repository (dotnetcore/mocha).
All paths below are relative to the repository root unless stated otherwise.
Mocha is an Application Performance Monitoring (APM) platform built on OpenTelemetry, providing a scalable pipeline for ingesting, storing, and querying observability data (traces, metrics, metadata).
- Language / Runtime: C# 12 on .NET 8 (
net8.0; noglobal.json, SDK pinned to8.0.xin CI). - Web stack: ASP.NET Core — gRPC (
Grpc.AspNetCore2.76.0) for ingest, Web API + Swagger (Swashbuckle.AspNetCore6.4.0) for query. - Storage backends (pluggable, per-signal): LiteDB 5.0.21 (embedded default), EF Core 8.0.5 +
Pomelo.EntityFrameworkCore.MySql8.0.2 (MySQL), InfluxDB (InfluxDB.Client4.16.0). - Codegen: OTLP protobuf via
Google.Protobuf3.35.1 +Grpc.Tools2.76.0 (from a git submodule); PromQL parser viaAntlr4.Runtime.Standard4.13.1 (requires JDK 17+ to regenerate). - Data flow:
Mocha.Distributor(OTLP gRPC ingest) → in-memoryBufferQueue→StorageExporterhosted service → pluggableMocha.Storage;Mocha.Queryserves PromQL- and Jaeger-compatible read APIs over the same storage.
CRITICAL: This repo uses a git submodule (
proto/otlp). Clone withgit clone --recursive, or rungit submodule update --init --recursivebefore building — otherwiseMocha.Protocol.Generatedwill not build.
| Directory | Purpose | Local Documentation |
|---|---|---|
src/Mocha.Core/ |
Shared domain models (Models/Trace, Models/Metrics, Models/Metadata), in-memory Buffer/Memory queue (IBufferQueue, MemoryBufferQueue), storage abstraction interfaces, OTel→Mocha conversion extensions |
– |
src/Mocha.Distributor/ |
ASP.NET Core gRPC host — OTLP export services (OTelTraceExportService, OTelMetricsExportService) + StorageExporter background service draining the buffer to storage |
– |
src/Mocha.Query/ |
ASP.NET Core Web API host — Prometheus/PromQL (Prometheus/PromQL/Engine) and Jaeger query surfaces |
– |
src/Mocha.Storage/ |
Storage providers: LiteDB/, EntityFrameworkCore/ (MySQL), InfluxDB/; per-signal provider selection |
– |
src/Mocha.Streaming/ |
Planned streaming/aggregator tier (RootNamespace=Mocha.Aggregator) — csproj only, no source yet |
– |
src/Mocha.Protocol.Generated/ |
Compiles upstream OTLP .proto (from proto/otlp submodule) into C# |
– |
src/Mocha.Antlr4.Generated/ |
ANTLR4-generated PromQL lexer/parser from PromoQL/*.g4 (needs JDK 17+) |
– |
tests/ |
xUnit unit tests (Mocha.Core.Tests, Mocha.Storage.Tests, Mocha.Query.Tests) + BenchmarkDotNet suites (*.Benchmarks) |
– |
proto/otlp/ |
Git submodule → open-telemetry/opentelemetry-proto (OTLP definitions) |
– |
docker/ |
docker-compose.yml (LiteDB), docker-compose-mysql-influxdb.yml, distributor/ + query/ Dockerfiles, Grafana provisioning |
– |
scripts/mysql/init/ |
MySQL seed scripts (trace.sql, metadata.sql) |
– |
docs/ |
Architecture, deployment, development guide, quick-start, proposals, roadmap | docs/development/guide.md |
Entry points (runnable hosts): src/Mocha.Distributor/Program.cs (gRPC, top-level statements) and src/Mocha.Query/Program.cs (Web API). Both use minimal hosting — no explicit Main.
Run from the repository root. Commands are transcribed from .github/workflows/dotnet-build.yml, CONTRIBUTING.md, and docs/development/guide.md.
# 0. Submodules are REQUIRED (proto/otlp) — do this first, once.
git submodule update --init --recursive
# 1. Restore
dotnet restore
# 2. Build — build the generated protocol module FIRST, then the whole solution.
dotnet build ./src/Mocha.Protocol.Generated
dotnet build
# 3. Format (see Testing section for the CI check form)
dotnet formatNotes:
- Build ordering is load-bearing:
dotnet build ./src/Mocha.Protocol.Generatedmust precede the fulldotnet build. - All documented commands use bare
dotnet build/dotnet test(no explicitMocha.slnargument, no-c Releaseon build). Do not invent adotnet build Mocha.sln -c Releaseform. Mocha.Antlr4.Generatedrequires JDK 17+ installed to regenerate the PromQL parser.
Local run via Docker Compose (from the docker/ directory; docs use the legacy hyphenated docker-compose):
cd docker
docker-compose up --build -d # default LiteDB stack
docker-compose -f docker-compose-mysql-influxdb.yml up --build -d # MySQL + InfluxDB variantEndpoints after startup: Distributor OTLP gRPC :4317, Query API :5775 (Swagger at /swagger in Development), Grafana :3000 (admin/admin); MySQL variant adds MySQL :3306 and InfluxDB :8086.
Test framework: xUnit (xunit 2.9.2, xunit.runner.visualstudio, Microsoft.NET.Test.Sdk 17.11.1) with FluentAssertions 6.12.1; Mocha.Query.Tests also uses Moq 4.20.72, Mocha.Storage.Tests uses EF Core InMemory. Tests use [Fact] / [Theory].
# All tests
dotnet test
# CI form: Release + coverage (coverlet). Codecov patch target 98% is ENFORCED; project target 70% is informational.
dotnet test -c Release --collect:"XPlat Code Coverage"
# A single test project
dotnet test tests/Mocha.Core.Tests
dotnet test tests/Mocha.Query.Tests
dotnet test tests/Mocha.Storage.Tests
# A single class / test (standard xUnit dotnet-test filter syntax)
dotnet test tests/Mocha.Core.Tests --filter "FullyQualifiedName~Mocha.Core.Tests.Conversions.OTelToMochaMetricConversionExtensionsTests"Benchmarks are BenchmarkDotNet and run via dotnet run (not dotnet test):
dotnet run -c Release --project tests/Mocha.Core.Benchmarks -- --filter "*"- Trunk:
mainis protected — (CRITICAL) all changes land via PR, never push directly tomain. - Branches: cut from
main, namedfeat/xxx,fix/xxx, ordocs/xxx. - Commits: Conventional Commits —
<type>: <description>(optional body). Types:feat,fix,refactor,docs,test,chore,perf,ci. - PR requirements (
CONTRIBUTING.md): fork + feature branch; the change must passdotnet build,dotnet test, anddotnet format --verify-no-changes; describe the change and motivation; pass CI; get maintainer review before merge. - Required CI checks (on PR to
main):.NET Build(Ubuntu/Windows/macOS matrix — includes format gate + tests + coverage),CodeQL(C#), andDocker Build & Scan(Trivy runs withexit-code: 0, so it does not fail the build). - No DCO/CLA sign-off, no PR template, and no
CODEOWNERSfile exist in this repo.
Enforced by .editorconfig (severity :suggestion) + dotnet format --verify-no-changes in CI (a hard CI failure) + in-build .NET analyzers (EnforceCodeStyleInBuild=true, AnalysisLevel=8.0). Nullable and ImplicitUsings are enabled. max_line_length = 120, 4-space indent.
Every .cs file MUST start with the MIT license header (also declared via file_header_template in .editorconfig):
// Licensed to the .NET Core Community under one or more agreements.
// The .NET Core Community licenses this file to you under the MIT license.Use var; file-scoped namespaces; Allman braces; braces even on single-line blocks:
// ✅ Correct
namespace Mocha.Core.Buffer;
public class BufferConsumer
{
private readonly IBufferQueue _queue; // private field: _camelCase with leading underscore
public void Consume()
{
var batch = _queue.Pull(); // var required
if (batch.IsEmpty)
{
return; // braces required even here
}
}
}// ❌ Wrong
namespace Mocha.Core.Buffer { // block-scoped namespace
public class BufferConsumer { // brace on same line (K&R)
private IBufferQueue queue; // missing _ prefix
public void Consume() {
BufferBatch batch = queue.Pull(); // explicit type instead of var
if (batch.IsEmpty) return; // missing braces
}
}
}Other rules: System.* usings sorted first; no this. qualifier; predefined types (int, not Int32); constant fields PascalCase. Note: TreatWarningsAsErrors and LangVersion are not set — compiler warnings do not fail the build, but the dotnet format gate does.
- ✅ Always run
git submodule update --init --recursivebefore building, anddotnet build ./src/Mocha.Protocol.Generatedbefore the full build. - ✅ Always prefix new
.csfiles with the MIT license header, use file-scoped namespaces,var, and_camelCaseprivate fields. - ✅ Always run
dotnet format --verify-no-changesanddotnet testbefore opening a PR — both are hard CI gates. - ✅ Always keep new/changed code covered — the Codecov patch target is 98% (enforced).
⚠️ Ask first before changing storage schemas (scripts/mysql/init/*.sql, EF Core models), the OTLP/gRPC service contracts, or Docker Compose topology — these are cross-cutting.⚠️ Ask first before starting work insidesrc/Mocha.Streaming/(unimplemented) or upgrading the target framework / major dependencies.- 🚫 Never commit into or hand-edit
proto/otlp/(it is an upstream submodule) or files undersrc/*.Generated/output. - 🚫 Never push directly to
mainor bypass the PR + review flow. - 🚫 Never commit secrets, credentials, or local DB/data volumes produced by
docker-compose.
README.md/README.zh-CN.md— project intro, feature set, architecture diagrams.CONTRIBUTING.md— contribution flow, commit/PR conventions.docs/development/guide.md— detailed local dev, build ordering, common issues.docs/architecture/overview.md— technical architecture.docs/quick-start/— Docker Compose quick start.docs/ROADMAP.md,docs/proposal/— direction and design proposals.SECURITY.md— security policy.
No top-level deepwiki/ exists in this repository.