PowerShell / PowerShell/DSC

Improve messaging for resources

Open
#1,058 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue-Enhancement Needs Triage
Dominant language
Rust
Stars
523
Forks
75
Avg merge
3d 16h
Merged PRs (30d)
24

Description

Summary of the new feature / enhancement

As a resource developer, integrating developer, and DSC user,
I want to be able to have useful data about messages emitted from resources included in the message DSC emits,
So that I can correctly correlate and investigate messages emitted when DSC invokes a resource.

Currently, DSC emits messages from resources with the following formats:

  • Console (info, warn, and error trace levels, default and plaintext formats):

    2025-08-15T14:42:53.970726Z  WARN PID 29072: Message from resource
    
  • Console (trace and debug trace levels, default and plaintext formats):

    2025-08-15T14:42:53.970726Z  WARN dsc_lib::dscresources::command_resource: 901: PID 34460: Message from resource
    
  • JSON (info, warn, and error trace levels, json format, pretty-printed for readability):

    {
      "timestamp": "2025-08-15T14:42:53.970726Z",
      "level": "WARN",
      "fields": {
        "message": "PID 28644: Simple message"
      }
    }
    
  • JSON (trace and debug trace levels, json format, pretty-printed for readability):

    {
      "timestamp": "2025-08-15T14:42:53.970726Z",
      "level": "WARN",
      "fields": {
        "message": "PID 28644: Simple message"
      },
      "target": "dsc_lib::dscresources::command_resource",
      "line_number": 901
    }
    

Proposal

In the current implementation, DSC munges the emitted message from the resource by inserting PID: <PID> before the emitted message, making the message syntax effectively PID: <PID> <Message>. Anyone processing the emitted message needs to make sense of the PID prefix and extract the message itself.

While the emitted message does indicate the PID for the process that raised the message, it doesn't indicate information about the resource that emitted it.

Ideally, the emitted trace should contain the following fields:

  • message - the message from the resource.
  • resource.process.pid - the PID for the resource invocation.
  • resource.type - the resource fully qualified type name
  • resource.name - the name of the resource instance when invoked in a configuration context (undefined or null when invoked with dsc resource * commands).
  • resource.operation - the operation the resource was invoked for.

While we can't effectively bubble up structured data from a resource at this time due to limitations in the tracing library, we can provide known-at-invocation metadata to help developers and users make sense of individual messages without requiring a user to read them in the broader context of emitted messages. Currently, to know which resource emitted a message, a user needs to evaluate prior messages from DSC - and those messages aren't necessarily available at trace levels warn or error.

This work would also ease the path towards collecting resource messages in the result output for configuration commands.

Proposed technical implementation details (optional)

In the current implementation, we use the invoke_command function to invoke operations for extensions and resources:

https://github.com/PowerShell/DSC/blob/73c95ca37bec1df4208ef95dd6ab05f3ac0dc9a6/dsc_lib/src/dscresources/command_resource.rs#L718-L729

invoke_command calls the run_process_async function, which calls log_stderr_line to process stderr from the resources:

https://github.com/PowerShell/DSC/blob/73c95ca37bec1df4208ef95dd6ab05f3ac0dc9a6/dsc_lib/src/dscresources/command_resource.rs#L663-L673

The log_stderr_line function is only called from run_process_async, which is only called from invoke_command, which is always used to invoke operations for resources (including adapters) and extensions.

Known call sites

The following callsites show where we use invoke_command in our code:

In every callsite, we know:

  1. The type name for the resource or extension being invoked
  2. The operation being invoked

In the current implementation, we can't get the name of the resource when invoked for a configuration operation. We would need to have a way to pass that context.

A minimally-disruptive implementation would be to extend invoke_command to take three additional parameters:

  • type_name - the fully qualified type name for the resource or extension.
  • command_type - either Extension or Resource
  • operation - String representation of the operation

Which we could then flow-down to the run_process_async and log_stderr_line functions.

More usefully/maintainably, we should consider extracting the process spawning code into a separate module (now that it's used by both resources and extensions) and define context structs we can use for bubbling up emitted messages from resource/extension commands:

pub enum CommandInvocationContext {
  Resource(ResourceCommandInvocationContext),
  Extension(ExtensionCommandInvocationContext),
}
pub struct ResourceCommandInvocationContext {
  // Ellided
}
pub struct ExtensionCommandInvocationContext {
  // Ellided
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in dsc_lib/src/dscresources/command_resource.rs by reading invoke_command, run_process_async, and log_stderr_line, then review the listed resource and extension call sites. Trace how invocation metadata can flow into emitted messages without losing existing formats. Done means resource and extension messages expose the requested invocation metadata, with resource names handled where available.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
observability
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.