Skip to content

Conversation

ldennington
Copy link
Contributor

@ldennington ldennington commented Jan 20, 2023

Add initial TRACE2 functionality, including:

  1. Small refactorings to make TryGetAssemblyVersion accessible
    outside of the DiagnosticCommand class and shared trace logic
    accessible from a TraceUtils class.
  2. Addition of a Trace2CollectorWriter class, which handles writing
    to the Telemetry Tool/OTel collector and a Trace2StreamWriter class,
    which handles writing to stderr/files.
  3. Basic TRACE2 functionality, including the ability to add writers to
    different format targets, logic to send messages to these writers, and
    the ability to release these writers before application exit.
  4. Support for session IDs.
  5. Ability for users to enable normal/event format targets.
  6. Writing Version, Start, and Exit events.

While this patch series does not represent all the TRACE2 events we plan
to implement, it does provide the opportunity to review and suggest changes
to the foundation these events are built on. It also provides the general pattern
that additional patches will use to implement new events, just in case that
needs to be tweaked.

Copy link
Contributor

@derrickstolee derrickstolee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for helping me refresh my C#. Lots of good stuff in here.

@jeffhostetler
Copy link

This looks like a good start. Thanks for all your work on this.

Copy link
Contributor

@mjcheetham mjcheetham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good so far! I have some comments about simplifying the collector/queue, going all in on GIT_ variables, and how we're instantiating Trace2 and the stopwatch.

@jeffhostetler
Copy link

I just responded to all of Matthew's questions that I had an opinion on.

@ldennington ldennington force-pushed the trace2-initial-events branch from 0e52b93 to a74b9c0 Compare January 26, 2023 22:07
@ldennington
Copy link
Contributor Author

ldennington commented Jan 26, 2023

Changes since v1:

  • CollectorWriter now inherits from DisposableObject.
  • Removed the GCM-specific TRACE2 and TRACE2_SID environment variables in favor of piggybacking off Git’s existing variables.
  • Updated comments on AddListener() to better describe its purpose.
  • Removed Stopwatch() in favor of calculating elapsed times using Unix timestamps. Additionally, updated times that were using DateTime.Now to DateTime.UtcNow.
  • Ensured event target parsing is correct for both Posix and Windows systems (using TrimUntilLastIndexOf and moved the logic into a new TryParseEventTarget() method in Trace2.cs. Handling for other event targets will happen in future PRs with their respective implementations.
  • Ensured there is always a version (even if it’s just a placeholder) to send to WriteVersion().
  • Ensured messages sent to the telemetry daemon/OTel collector always end with a line feed.
  • Ensured we’re making a call to WriteExit().
  • Fixed incorrect implementation of DisposableObject in Trace2.cs and CollectorWriter.cs.
  • Removed state from CollectorWriter in favor of a Failed flag.
  • Condensed Sid logic - updated method name from GetSid() to SetSid() and moved call to Trace2 constructor.
  • Ensured we are writing the correct args in WriteStart().

@ldennington ldennington force-pushed the trace2-initial-events branch from a74b9c0 to f402706 Compare January 26, 2023 23:03
public static void Main(string[] args)
{
// Set up timer for TRACE2
var applicationStartTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just made a comment in Trace2.c about moving all of the time-math into it, but I wanted to say that we should be careful converting UTC times to seconds -- we're measuring mili- and micro-second times and here we're lopping of the time to integer seconds. There is a To...Milliseconds() method that would be better (inside the WriteFOO() events).

That is assuming that there isn't a way to have the WriteFOO() methods subtract two DateTime values directly and get an elapsed TimeSpan expressed in a microsecond value and then format that as a time-in-seconds floating point value in the JSON event.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I've got an extension method that's doing what we want here. Let me know what you think.

@ldennington ldennington force-pushed the trace2-initial-events branch from f402706 to 72fd03f Compare January 31, 2023 20:14
@ldennington
Copy link
Contributor Author

Changes since v2:

  1. Removed local pipe variable from CollectorWriter Start() method.
  2. Removed af_unix:./test.uds and //./pipe/ string literals from IsTrace2TracingEnabled test.
  3. Updated all times to microseconds (with the help of a new DateTimeOffset extension ToUnixTimeMicroseconds).
  4. Calculated elapsed time for Start and Exit events in the methods that write these events (rather than calculating in the caller(s)).

@ldennington ldennington force-pushed the trace2-initial-events branch 2 times, most recently from 0bee0da to b1052e5 Compare January 31, 2023 21:06
@ldennington ldennington force-pushed the trace2-initial-events branch 2 times, most recently from 23e683e to 74916cd Compare February 6, 2023 17:32
Copy link
Contributor

@mjcheetham mjcheetham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments I have so far

@ldennington
Copy link
Contributor Author

Changes since v3:

  1. Re-architected solution to more easily extend to additional event format targets and outputs (stderr/file). I have diagrammed the main components of the new solution in the hopes it’ll make it easier for reviewers to parse this PR (recommended to open in a separate window for viewing):
    trace2
  2. Added support for the normal format target.
  3. Refactored shared Trace logic into a new TraceUtils class.
  4. Re-organized calling of current events (Version, Start, and Exit) to occur via Start and Stop methods.
  5. Updated application start time to be a DateTimeOffset rather than a long. This removed the need for a DateTimeOffsetExtensions class to convert to and from Unix time stamps.
  6. Formatting updates to correctly write all events to different event format targets and outputs:
    • Writing all file names and paths in lower case.
    • Ensuring the Time field is the time at which the event is being written (rather than the application start time).
    • Writing in local time for the normal format target and UTC time for the event format target.
    • Ensuring line numbers are written as integers (rather than doubles).

@ldennington ldennington force-pushed the trace2-initial-events branch 2 times, most recently from 463f3f4 to 3b22601 Compare February 7, 2023 19:10
Lessley Dennington added 5 commits February 7, 2023 15:52
The implementation of TRACE2 tracing will require use of the
TryGetAssemblyVersion method. To prepare for this, move this method out
of the DiagnoseCommand class and into its own static class.
The implementation of TRACE2 tracing will require truncation of long file
names just as TRACE does. To prepare for this, move this logic out of the
TRACE class and into its own method in a new static TraceUtils class.
Additionally, add a unit test to validate this logic.
Add initial TRACE2 functionality, including:

1. The ability to add writers (which will eventually write to Normal, Perf, and Event
format targets).
2. An abstract Trace2Message class.
3. Logic to send Trace2Messages to writers.
4. Ability to release writers prior to application exit.
Add the Trace2CollectorWriter class to accept Trace2 messages in the event target
format and write them to the OTel Collector/Telemetry Service.
Add Trace2StreamWriter class which will be used to write to stderr or a
file, based on the TextWriter that is passed to it. It will also adapt the
output format based on the format target that is passed to it.
@ldennington ldennington force-pushed the trace2-initial-events branch from 3b22601 to 9688226 Compare February 7, 2023 22:53
Copy link
Contributor

@derrickstolee derrickstolee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a quick look through, and only had some nitpicks along the way.

However, one thing I was looking forward to seeing was a test that could demonstrate that the git-credential-manager executable would output the trace2 output (in event or normal form) as much as possible. The event form creates a JSON event on a per-line basis, so being able to parse that JSON even and checking that it has the necessary items would be helpful. (Any issues with extra items?)

Lessley Dennington added 2 commits February 8, 2023 13:16
A key component of Git's TRACE2 tracing system is the session id (sid).
This identifies the process instance to allow all events emitted by it to
be identified.

We check to see if a parent sid (i.e. from a Git process) exists. If so,
we separate this sid from the GCM sid (a GUID) using a "/". If there is no
parent sid, we simply generate a GUID for the GCM sid and use that.

The above also requires addition of a new SetEnvironmentVariable() method
in EnvironmentBase.cs to set the GCM-specific SID variable.
Add the infrastructure to detect whether a user has enabled the TRACE2
event format or normal format targets. This implementation has been
designed to be extended to include the perf format target in a future
series.

Additionally it involved some refactoring/cleanup to set the Application
Path and InstallationDirectory in the CommandContext, rather than in
GCM/UI helper Program.cs files.
Copy link
Contributor

@derrickstolee derrickstolee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit: Looks like a strong foundation and anything from here on out can be forward-fixed as we get more use out of it (and an end-to-end testing framework).

Lessley Dennington added 2 commits February 10, 2023 09:28
Write the TRACE2 version event, which identifies the event format version
(currently hardcoded as 3 as it is in Git) and the version of GCM.

Additionally, write the TRACE2 start event, which reflects the elapsed time and
application arguments (including the application name). These are paired
because the telemetry tool/OTel collector require both these events to be
sent for a given session.
Add TRACE2 exit event, following the pattern established with the version
and start events.
@ldennington ldennington force-pushed the trace2-initial-events branch from 995d6b7 to 028ad46 Compare February 10, 2023 16:32
@ldennington ldennington merged commit fb1942a into git-ecosystem:main Feb 10, 2023
@jeffhostetler
Copy link

You merged it as I was about to push the approve button.... :-)
This looks good. Nice work.
This will give us a chance to kick the tires now. Thanks.

@ldennington ldennington deleted the trace2-initial-events branch July 12, 2023 18:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants