Coject.Core.Logging.Cscc
1.0.1
dotnet add package Coject.Core.Logging.Cscc --version 1.0.1
NuGet\Install-Package Coject.Core.Logging.Cscc -Version 1.0.1
<PackageReference Include="Coject.Core.Logging.Cscc" Version="1.0.1" />
<PackageVersion Include="Coject.Core.Logging.Cscc" Version="1.0.1" />
<PackageReference Include="Coject.Core.Logging.Cscc" />
paket add Coject.Core.Logging.Cscc --version 1.0.1
#r "nuget: Coject.Core.Logging.Cscc, 1.0.1"
#:package Coject.Core.Logging.Cscc@1.0.1
#addin nuget:?package=Coject.Core.Logging.Cscc&version=1.0.1
#tool nuget:?package=Coject.Core.Logging.Cscc&version=1.0.1
Coject Core Logging CSCC Adapter
Coject.Core.Logging.Cscc is the optional CSCC destination for the provider-neutral Coject logging pipeline. It registers separate pooled HTTP clients for log and audit lanes, sends canonical Contracts 3.0 JSON, and reuses Core’s bounded ownership, retry, outbox, circuit-breaker, local JSONL, redaction, and shutdown boundaries.
This package is the transport adapter only. It does not depend on CojectCore.Controller, does not register MVC controllers or routes, and does not contain the legacy flat CSCC sender. It depends on Coject.Core.Logging because the adapter implements Core’s destination handoff interface.
Package and support
- Package:
Coject.Core.Logging.Csccversion1.0.1 - Target framework:
net8.0 - Required Core package:
Coject.Core.Logging1.0.0 - Core wire contract:
Coject.Core.Logging.Contracts3.0.0transitively - Repository: https://github.com/coject/CojectCore
- The package contains portable symbols (
.snupkg) and the packagedREADME.md, license, and icon.
Installation
<PackageReference Include="Coject.Core.Logging.Cscc" Version="1.0.1" />
The project reference to Coject.Core.Logging is intentional and becomes a package dependency when packed. CojectCore.Controller is not a dependency: applications can use Controller and logging packages side by side without adding Controller types to the logging runtime graph.
Registration
Use the CSCC host-level extension. It registers Core and then the CSCC adapter; registration is idempotent.
using Coject.Core.Logging.Cscc;
var builder = Host.CreateApplicationBuilder(args);
builder.AddCojectLoggingCscc();
using var host = builder.Build();
await host.RunAsync();
For ASP.NET Core:
using Coject.Core.Logging.Cscc;
var builder = WebApplication.CreateBuilder(args);
builder.AddCojectLoggingCscc();
var app = builder.Build();
app.MapGet("/", () => Results.Ok("running"));
app.Run();
AddCojectLoggingCscc() calls the Core registration boundary and registers the adapter only when CojectLogging:Cscc:Enabled is exactly true. When disabled, the application remains local-only and no CSCC HTTP clients or remote calls are created. The optional host argument is the same Core coexistence switch:
builder.AddCojectLoggingCscc(options =>
options.ReplaceExistingFrameworkProviders = false);
The default is true, which removes previously registered framework ILoggerProvider instances so there is one ownership path. Set it to false only for a deliberate migration.
Complete appsettings.json tree
This is the complete bindable configuration graph used by Core and the CSCC adapter. The API key is a placeholder only. Keep CSCC disabled until the endpoint and secret provider are configured.
{
"CojectLogging": {
"Environment": "Production",
"TrustedContext": {
"KnownProxies": [],
"KnownNetworks": [],
"ForwardLimit": 1,
"PresentationTimeZoneId": "Asia/Riyadh"
},
"Local": {
"RootPath": "logs",
"Application": {
"Enabled": true,
"RetentionDays": 30,
"MaxSegmentSizeBytes": 104857600,
"BatchSize": 100,
"FlushIntervalMilliseconds": 1000
},
"Audit": {
"Enabled": true,
"RetentionDays": 365,
"MaxSegmentSizeBytes": 104857600,
"BatchSize": 20,
"FlushIntervalMilliseconds": 500
}
},
"Cscc": {
"Enabled": true,
"AppId": "sample-service",
"Endpoint": "https://cscc.example.invalid",
"ApiKey": "<YOUR_CSCC_API_KEY>",
"ContractVersion": "3.0",
"Scopes": [
"logging.write",
"audit.write"
],
"Delivery": {
"LogConcurrency": 4,
"AuditConcurrency": 2,
"AttemptTimeoutSeconds": 10
},
"CircuitBreaker": {
"FailureThreshold": 5,
"InitialCooldownSeconds": 30,
"MaxCooldownSeconds": 300,
"JitterRatio": 0.2,
"RateLimitPauseMinimumSeconds": 1,
"RateLimitPauseMaximumSeconds": 3600
}
},
"Queues": {
"Memory": {
"Logs": {
"MaxRecords": 10000,
"MaxBytes": 134217728
},
"Audits": {
"MaxRecords": 1000,
"MaxBytes": 268435456
}
},
"Overflow": {
"Logs": {
"MaxRecords": 25000,
"MaxBytes": 536870912
},
"Audits": {
"MaxRecords": 5000,
"MaxBytes": 1073741824
},
"HighSeverityReservationPercent": 25
},
"HighSeverityBurstLimit": 8,
"EnqueueTimeoutMs": 25,
"HandoffRetryInitialDelaySeconds": 1,
"HandoffRetryMaxDelaySeconds": 60,
"ShutdownDrainTimeoutSeconds": 10
},
"Outbox": {
"Retry": {
"InitialDelaySeconds": 2,
"Multiplier": 2,
"MaxDelaySeconds": 300,
"RetryAfterMinimumSeconds": 1,
"RetryAfterMaximumSeconds": 3600
},
"Logs": {
"MaxRecords": 100000,
"MaxBytes": 2147483648,
"HighSeverityReservationPercent": 25,
"QuarantineRetentionDays": 90
},
"Audits": {
"MaxRecords": 20000,
"MaxBytes": 4294967296,
"HighSeverityReservationPercent": 25,
"QuarantineRetentionDays": 365
}
},
"Redaction": {
"AdditionalSensitiveFields": []
},
"Health": {
"EmergencyDiagnosticMinimumIntervalSeconds": 60,
"Disk": {
"WarningFreeSpacePercent": 10,
"WarningFreeSpaceBytes": 2147483648,
"CriticalFreeSpacePercent": 5,
"CriticalFreeSpaceBytes": 536870912,
"CheckIntervalSeconds": 30
}
},
"Framework": {
"Enabled": true,
"MinimumLevel": "Information"
}
}
}
Property behavior and limits
Environmentdefaults toProductionand must contain 1–64 printable characters.TrustedContext.KnownProxiescontains canonical proxy IPs,KnownNetworkscontains aligned CIDR networks, and each list has at most 100 unique entries.ForwardLimitis 1–8.PresentationTimeZoneIddefaults toAsia/Riyadhand changes presentation only.Local.RootPathis a safe path resolved from the process working directory. It cannot contain control characters, wildcards, or... Local application and audit sinks are mandatory in the binding boundary; a missing or false sink binding is normalized to its enabled default in this release. Keep bothEnabledvalues true.- Local
RetentionDaysis 1–3650, segment size is 1–1073741824 bytes,BatchSizeis 1–1000, and flush interval is 50–5000 milliseconds. - With
Cscc.Enabledfalse, Core is local-only and endpoint/key/scope identity values are not required. With it true,AppIdis a non-empty identifier of at most 128 characters;Endpointis an absolute HTTPS URI without user information;ApiKeyis one scalar value of 32–512 non-whitespace characters; andContractVersionmust be exactly3.0. - Supported scopes are exactly
logging.writeandaudit.write. Scopes must be unique and includelogging.write; includeaudit.writefor audit delivery. Cscc.Delivery.LogConcurrencyandAuditConcurrencyare 1–32, combined maximum 64, andAttemptTimeoutSecondsis 1–60.CircuitBreaker.FailureThresholdis positive; cooldown and rate-limit values are positive finite numbers; maximums cannot be below minimums; andJitterRatiois greater than zero and at most 1.- Memory capacities are 1–1000000 records and 1–4294967296 bytes.
HighSeverityBurstLimitis 1–100, enqueue timeout is 1–250 milliseconds, handoff retry delays are 1–60 and 1–300 seconds with maximum not below initial, and shutdown drain is 1–30 seconds. - Overflow and outbox
HighSeverityReservationPercentis fixed at 25 in v1. Outbox capacities are 1–10000000 records and 1–17179869184 bytes; quarantine retention is 1–3650 days. - Outbox retry delays and Retry-After bounds are positive finite values no greater than 3600 seconds; multiplier is 1–10; maximums cannot be below minimums.
Redaction.AdditionalSensitiveFieldsaccepts at most 100 non-empty printable names of at most 128 characters.HealthandDiskenforce positive thresholds, critical thresholds below warning thresholds, a diagnostic interval of 1–3600 seconds, and disk checks of 5–300 seconds.Framework.EnabledandMinimumLevelapply only to the compatibilityILoggerProvider; explicit typedICojectLoggercalls are not filtered by this minimum level.
CSCC contract and transport
The adapter uses the configured endpoint as a base and posts:
- logs to
/api/v3/ingest/logs - audits to
/api/v3/ingest/audits
Requests have Content-Type: application/json, X-API-Key, and X-Correlation-ID headers. The body is the exact redacted canonical Contracts 3.0 UTF-8 record produced by Core. The root is nested, not the legacy flat audit object:
{
"envelope": {
"contractVersion": "3.0",
"eventType": "DataModification",
"actionType": "Update",
"occurredAt": "2026-01-01T12:00:00.000Z",
"serviceName": "SampleService",
"environment": "Production",
"module": "Orders",
"resource": "Order",
"operation": "Update",
"entityId": "123",
"correlationId": "sample-correlation-123",
"actor": {
"type": "User",
"id": "42"
}
},
"payload": {
"oldValues": {},
"newValues": {},
"changedFields": ["Status"]
}
}
The provider treats HTTP 201 as success only when the JSON acknowledgement contains success: true, a string recordId, the matching correlationId, and a contractVersion. Response bodies are bounded and only safe error codes are retained; credentials and arbitrary provider text are not copied into diagnostics.
The legacy CsccLogService shape is not used by this package. Do not send a flat { username, actionType, eventType, changes, metadata, ... } object to the v3 endpoint.
Typed logging and auditing
The CSCC package exposes Core’s ICojectLogger through its Core dependency:
using Coject.Core.Logging.Contracts;
using Coject.Core.Logging.Contracts.Payloads;
var logger = host.Services.GetRequiredService<ICojectLogger>();
var result = await logger.LogAsync(
CojectEvents.SystemExecution(new SystemExecutionPayload(stepName: "cscc-startup")),
CojectLogLevel.Info,
"CSCC logging verification");
Console.WriteLine($"{result.Status}: {result.Reason}");
Audits must be created with closed Contracts factories and submitted after the business transaction commits:
CojectAuditAction<DataModificationPayload> action =
CojectAuditActions.DataModification(
new DataModificationPayload(
oldValues: oldPersistedSnapshot,
newValues: newPersistedSnapshot));
var result = await logger.AuditAsync(action);
The trusted context provider must supply Module, Resource, and Operation for audits. A missing or incomplete snapshot, invalid action/event pair, or no-change modification is rejected before any CSCC request.
Local JSONL and audit behavior
CSCC delivery never replaces local persistence. Core writes separate application and audit lanes under:
<working-directory>/logs/<service>/<environment>/<instance>/local/application/
<working-directory>/logs/<service>/<environment>/<instance>/local/audit/
Files are named application-...-00000001.jsonl and audit-...-00000001.jsonl. Each lane has its own queue, writer lock, batch/flush policy, segment rotation, retention, and quarantine directory. The local audit body is the same canonical Contracts 3.0 record sent to CSCC.
Failure, retry, spool, and circuit behavior
The Core enqueue boundary is bounded by Queues.EnqueueTimeoutMs. Accepted immutable records enter independent log/audit memory lanes. Overflow uses the protected instance spool:
<instance-root>/spool/logs/
<instance-root>/spool/audits/
CSCC then has independent log and audit HTTP lanes with LogConcurrency, AuditConcurrency, and AttemptTimeoutSeconds. Provider outbox state is separate from the Core spool. Unresolved records remain durable until confirmation, permanent failure, quarantine, or an explicit reconciliation decision.
Transient network failures, timeouts, HTTP 408/425, HTTP 429, and HTTP 5xx responses are retried within configured bounds. A valid integer Retry-After on 429 is honored for up to one hour and constrained by the configured pause limits. The circuit breaker opens after the configured consecutive transient-failure threshold and uses bounded cooldown with jitter.
When a log or audit attempt raises a transport exception or reaches its bounded
timeout, the adapter emits one fixed-content warning through Core's existing
local-only ILogger compatibility path. Core records that warning as typed
SystemExecution telemetry without re-entering CSCC; the original handoff
result, retry/ownership behavior, and redaction boundary are unchanged. The
warning does not contain endpoint, API key, exception text, response content,
JWT, or payload data.
HTTP 401 is an authentication failure and HTTP 403 is a scope failure. HTTP 400, 404, 405, 413, 415, 422, and other ordinary 4xx responses are permanent failures. In particular, HTTP 422 is classified as PERSISTENCE_VALIDATION_FAILED; it does not open the breaker and is not blindly retried. HTTP 409 and selected client-disconnect/transport cases are uncertain and retained for reconciliation because delivery may have committed remotely.
On graceful shutdown, Core closes intake, drains within ShutdownDrainTimeoutSeconds, and spills unresolved ownership. Await host shutdown so durable handoff can finish.
Redaction and security
- Use a secret manager or environment-variable override for
CojectLogging:Cscc:ApiKey. Never put a real key inappsettings.json, source, README, logs, package contents, or issue reports. - The key is sent only as
X-API-Key. It is not included in the canonical envelope, local record, outbox metadata, or health snapshot. - Use an absolute HTTPS endpoint with no user information. The adapter does not follow redirects and does not use cookies.
- Core redacts built-in sensitive names before local and CSCC delivery. Add application-specific names through
Redaction.AdditionalSensitiveFields; do not try to disable built-in redaction. - Restrict scopes to
logging.writeandaudit.write, grant only the lanes required by the application, and keepAppIdstable and non-secret. - Configure
KnownProxiesandKnownNetworksonly for trusted infrastructure. Forwarded IP values must be rebuilt by that edge and must match the configured trust policy. - System actors do not carry producer actor IPs. User and anonymous actors may carry a trusted normalized originating address. Correlation IDs are validated and transport headers must agree with the envelope.
Correlation, actor, and IP behavior
Core prefers a valid X-Correlation-ID, then an envelope correlation ID, then generates one. If both are supplied they must match. IDs are 8–64 safe ASCII characters. Canonical timestamps are UTC at millisecond precision; PresentationTimeZoneId is display-only.
The actor model supports user, system, and anonymous actors. User/system actors require stable IDs and display names are bounded. Request context is closed to correlationId, module, resource, operation, entityId, and statusCode; arbitrary client fields cannot overwrite server-owned context. Status codes are limited to 100–599.
Minimal verification
- Install
Coject.Core.Logging.Csccand registerAddCojectLoggingCscc(). - Set
Cscc.Enabledtotrue, replace the placeholder endpoint and key through deployment configuration, and set scopes appropriate to the enabled lanes. - Run the
SystemExecutionexample and confirm both a local application JSONL record and a CSCC log request. - Submit a closed audit action after commit with module/resource/operation context and confirm the local audit record plus a
201CSCC acknowledgement. - Inspect
ICojectLoggingHealthfor safe queue, spool, outbox, disk, and circuit state. Do not inspect or print the API key.
Troubleshooting
| Symptom | Check |
|---|---|
| No CSCC HTTP activity | Confirm the adapter package is installed, AddCojectLoggingCscc() is called, Cscc.Enabled is true, and startup validation succeeds. |
| Startup validation fails | Check exact ContractVersion 3.0, absolute HTTPS endpoint, scalar 32–512 character key, unique supported scopes, delivery bounds, and circuit-breaker bounds. |
| HTTP 401 | The API key is missing, invalid, expired, or not associated with the configured application. Rotate it through the secret provider; do not put it in source. |
| HTTP 403 | Grant the required logging.write or audit.write scope for the failing lane. |
| HTTP 422 | This is a permanent provider validation failure. Verify the server accepts the canonical nested { "envelope": {}, "payload": {} } Contracts 3.0 root, event/action pair, required audit context, and payload completeness. Do not add blind retry. |
| HTTP 201 but no confirmation | The response must be JSON with success: true, recordId, matching correlationId, and contractVersion; otherwise it is treated as an invalid success response and retained as failure. |
| HTTP 429 or 5xx | Check Retry-After, circuit state, outbox quota, endpoint availability, and retry bounds. These statuses are retryable within policy. |
| Local records exist but CSCC does not | This is expected when CSCC is disabled or provider delivery is unavailable. Inspect outbox/spool health and quarantine without deleting records manually. |
| Audit is rejected before transport | Use a closed Contracts audit factory, submit after commit, provide old/new snapshots as required, and supply module/resource/operation context. |
Dependency decision
The CSCC project references Coject.Core.Logging as a project reference because it implements Core’s ICojectDestinationHandoffAdapter boundary and consumes Core options, queues, outbox, and destination handoff types. It does not reference CojectCore.Controller; no Controller API is required for transport registration or delivery.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Coject.Core.Logging (>= 1.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Http (>= 9.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Patch release for bounded CSCC transport-failure and timeout warning telemetry through Core's existing local-only ILogger compatibility path. Preserves handoff results, redaction, and separate log/audit HTTP clients.