Skip to content

Latest commit

 

History

History
201 lines (184 loc) · 10.8 KB

Error Log Format.md

File metadata and controls

201 lines (184 loc) · 10.8 KB

The C# and Visual Basic compilers support a /errorlog: switch on the command line to log all diagnostics in a structured, JSON format.

The log format is SARIF (Static Analysis Results Interchange Format): See https://sarifweb.azurewebsites.net/ for the format specification, JSON schema, and other related resources.

SARIF v2 format

This section provides a high level overview of the contents of the SARIF v2 error log file generated by the C# and Visual Basic compilers. A more formal and detailed schema specification for the SARIF v2 format is specified at http://json.schemastore.org/sarif-2.1.0.

  1. schema and version information: The first two lines of the error log file specifies the SARIF schema and version information. For example:
"$schema": "http://json.schemastore.org/sarif-2.1.0",
"version": "2.1.0",
  1. runs information: The core entry in the error log file is the runs section with a single run entry within it for the build. The run entry has the following main parts:
    1. results section: This section contains an array of result entries, where each result corresponds to information about a reported compiler or analyzer Diagnostic. More details in Result format for each compiler or analyzer Diagnostic instance.
    2. properties section: This section contains custom key-value properties associated with the run. Following properties are currently emitted:
      1. analyzerExecutionTime: Execution time in seconds for execution of all analyzers, as reported with the /reportAnalyzer compiler switch.
    3. tools section: This section contains information about the compiler build and version. Additionally, it contains a rules array, where each rule entry corresponds to metadata or DiagnosticDescriptor information about each reported analyzer diagnostic. More details in Rule format for each analyzer supported DiagnosticDescriptor instance
    4. invocations section: This section contains information about the end user specified configurations for the rules for compiler invocation/run. We emit this section only if at least one rule had one or more severity configuration overrides for a part or whole of the compilation via options. More details in Rule Configuration Override format for each rule severity override.
    5. columnKind section: This section contains information about the unit in which the tool measures columns. C# and Visual Basic compilers uses utf16 code units.

Example runs section, with stripped off results, rules and ruleConfigurationOverrides sections:

"runs": [
{
  "results": [
  ],
  "properties": {
    "analyzerExecutionTime": "x.xxx"
  },
  "tool": {
    "driver": {
      "name": "Microsoft (R) Visual C# Compiler",
      "version": "4.4.0-dev (<developer build>)",
      "dottedQuadFileVersion": "42.42.42.42",
      "semanticVersion": "42.42.42",
      "language": "en-US",
      "rules": [
      ]
    }
  },
  "invocations": [
    {
      "executionSuccessful": true,
      "ruleConfigurationOverrides": [
      ]
    }
  ],
  "columnKind": "utf16CodeUnits"
}
]

Result format for each compiler or analyzer Diagnostic instance

The results section contains an array of result entries, where each result corresponds to information about a reported compiler or analyzer Diagnostic. It contains the below data:

  1. ruleId: Rule ID or diagnostic ID for the diagnostic.
  2. ruleIndex: Index into the rules section for the underlying DiagnosticDescriptor for the diagnostic. See Rule format for each analyzer supported DiagnosticDescriptor instance for more details.
  3. level: Severity level for the diagnostic, such as error, warning, note, etc.
  4. message: User facing message for the diagnostic.
  5. suppressions: For each diagnostic instance that is suppressed with a pragma directive, SuppressMessageAttribute or via a DiagnosticSuppressor, the result entry contains suppressions section with the following data:
    1. kind information: C# and Visual Basic compilers support a single inSource suppression kind.
    2. justification information: Justification pertaining to the suppression. Currently, this field is populated only for SuppressMessageAttribute based suppression, with a non-null justification argument.
    3. suppressionType property with one of these three values: Pramga Directive, SuppressMessageAttribute, or DiagnosticSuppressor. This data helps analyze the preferred in-source suppression mechanisms in a code base.
  6. locations: One or more locations associated with the diagnostic.
  7. properties: One or more custom key-value string pairs associated with the diagnostic.

Example result entry:

{
  "ruleId": "CA1822",
  "ruleIndex": 97,
  "level": "warning",
  "message": {
    "text": "Member 'M2' does not access instance data and can be marked as static"
  },
  "suppressions": [
  {
    "kind": "inSource",
    "justification": "<Pending>",
    "properties": {
      "suppressionType": "SuppressMessageAttribute"
    }
  }
  ],
  "locations": [
  {
    "physicalLocation": {
      "artifactLocation": {
        "uri": "file:///C:/source/repos/ClassLibrary1/Class1.cs"
      },
      "region": {
        "startLine": 13,
        "startColumn": 10,
        "endLine": 13,
        "endColumn": 12
      }
    }
  }
  ],
  "properties": {
    "warningLevel": 1
  }
}

Rule format for each analyzer supported DiagnosticDescriptor instance

The rules section contains a rule entry that corresponds to metadata or DiagnosticDescriptor information about supported descriptors for each analyzer. We report the DiagnosticDescriptor info for all analyzers that were provided to the compilation, regardless of whether or not they executed on the entire compilation, part of the compilation or were disabled for the entire compilation. A rule entry contains the below data:

  1. id: Rule ID or Diagnostic ID associated with the descriptor.
  2. shortDescription: User facing short description or Title associated with the descriptor.
  3. fullDescription: User facing full description or Description associated with the descriptor.
  4. defaultConfiguration: Default severity level for the diagnostics reported for the descriptor, such as error, warning, note, etc.
  5. helpUri: Help uri for help information associated with the descriptor.
  6. properties: One or more custom properties associated with the descriptor. It includes the following:
    1. category: Category associated with the descriptor, such as, Design, Performance, Security, etc.
    2. isEverSuppressed and suppressionKinds: If a rule had either a source suppression or was disabled for part or whole of the compilation via options, the rule metadata contains a special flag isEverSuppressed = true and an array suppressionKinds with either or both of the below suppression kinds:
      1. inSource suppression kind for one or more reported diagnostic(s) that were suppressed through pragma directive, SuppressMessageAttribute or a DiagnosticSuppressor.
      2. external suppression kind for diagnostic ID that is disabled either for the entire compilation (via global options such as /nowarn, ruleset, globalconfig, etc.) or for certain files or folders in the compilation (via editorconfig options).
    3. executionTimeInSeconds: Execution time in seconds associated with the analyzer, as reported with the /reportAnalyzer compiler switch. Values less than 0.001 seconds are reported as <0.001.
    4. executionTimeInPercentage: Execution time in percentage associated with the analyzer, as reported with the /reportAnalyzer compiler switch. Values less than 1 are reported as <1.
    5. tags: An array of one of more CustomTags associated with the descriptor.

Example rule entry:

{
  "id": "CA1001",
  "shortDescription": {
    "text": "Types that own disposable fields should be disposable"
  },
  "fullDescription": {
    "text": "A class declares and implements an instance field that is a System.IDisposable type, and the class does not implement IDisposable. A class that declares an IDisposable field indirectly owns an unmanaged resource and should implement the IDisposable interface."
  },
  "defaultConfiguration": {
    "level": "note"
  },
  "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1001",
  "properties": {
    "category": "Design",
    "isEverSuppressed": "true",
    "suppressionKinds": [
      "external"
    ],
    "executionTimeInSeconds": "x.xxx",
    "executionTimeInPercentage": "xx",
    "tags": [
      "PortedFromFxCop",
      "Telemetry",
      "EnabledRuleInAggressiveMode"
    ]
  }
}

Rule Configuration Override format for each rule severity override

The ruleConfigurationOverrides section contains an array of entries, with an entry for every rule severity configuration override for the whole or part of the compilation via options, i.e. editorconfig, globalconfig, command line options, ruleset, etc. Each rule configuration override entry contains the following information:

  1. descriptor: Property containing information to map back to the relevant descriptor or the rule in the rules section. Currently, it contains the below child properties:
    1. id: Rule id string for the rule or diagnostic.
    2. index: A zero-based integral index value into the rules array for the rule mapping.
  2. configuration: Configuration property for the effective overridden severity for the rule. Currently, it may include one of the below child properties:
    1. enabled: A boolean property indicating if the rule has been explicitly disabled or enabled with the configuration override entry.
    2. level: Property for the effective severity of the rule, such as error, warning or note. Note that this property is not emitted for rules disabled with configuration override, we instead emit enabled: false for them.

Note that we can have multiple ruleConfigurationOverride entries for the same descriptor if the rule is configured to fire at different severities across different parts of the compilation. For example, editorconfig based severity configurations can specify different effective severity for the same rule ID for different files or folders in a project.

Example ruleConfigurationOverride entry:

{
  "descriptor": {
    "id": "CA1000",
    "index": 0
  },
  "configuration": {
    "level": "error"
  }
},
{
  "descriptor": {
    "id": "CA1000",
    "index": 0
  },
  "configuration": {
    "enabled": false
  }
},
{
  "descriptor": {
    "id": "CA1001",
    "index": 1
  },
  "configuration": {
    "level": "warning"
  }
}