blob: 74714900e4f726afea67af7fc83f75828e711a95 [file] [log] [blame]
Junio C Hamano11f15372019-03-07 03:17:001<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
5<head>
6<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
7<meta name="generator" content="AsciiDoc 8.6.10" />
8<title>Trace2 API</title>
9<style type="text/css">
10/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
11
12/* Default font. */
13body {
14 font-family: Georgia,serif;
15}
16
17/* Title font. */
18h1, h2, h3, h4, h5, h6,
19div.title, caption.title,
20thead, p.table.header,
21#toctitle,
22#author, #revnumber, #revdate, #revremark,
23#footer {
24 font-family: Arial,Helvetica,sans-serif;
25}
26
27body {
28 margin: 1em 5% 1em 5%;
29}
30
31a {
32 color: blue;
33 text-decoration: underline;
34}
35a:visited {
36 color: fuchsia;
37}
38
39em {
40 font-style: italic;
41 color: navy;
42}
43
44strong {
45 font-weight: bold;
46 color: #083194;
47}
48
49h1, h2, h3, h4, h5, h6 {
50 color: #527bbd;
51 margin-top: 1.2em;
52 margin-bottom: 0.5em;
53 line-height: 1.3;
54}
55
56h1, h2, h3 {
57 border-bottom: 2px solid silver;
58}
59h2 {
60 padding-top: 0.5em;
61}
62h3 {
63 float: left;
64}
65h3 + * {
66 clear: left;
67}
68h5 {
69 font-size: 1.0em;
70}
71
72div.sectionbody {
73 margin-left: 0;
74}
75
76hr {
77 border: 1px solid silver;
78}
79
80p {
81 margin-top: 0.5em;
82 margin-bottom: 0.5em;
83}
84
85ul, ol, li > p {
86 margin-top: 0;
87}
88ul > li { color: #aaa; }
89ul > li > * { color: black; }
90
91.monospaced, code, pre {
92 font-family: "Courier New", Courier, monospace;
93 font-size: inherit;
94 color: navy;
95 padding: 0;
96 margin: 0;
97}
98pre {
99 white-space: pre-wrap;
100}
101
102#author {
103 color: #527bbd;
104 font-weight: bold;
105 font-size: 1.1em;
106}
107#email {
108}
109#revnumber, #revdate, #revremark {
110}
111
112#footer {
113 font-size: small;
114 border-top: 2px solid silver;
115 padding-top: 0.5em;
116 margin-top: 4.0em;
117}
118#footer-text {
119 float: left;
120 padding-bottom: 0.5em;
121}
122#footer-badges {
123 float: right;
124 padding-bottom: 0.5em;
125}
126
127#preamble {
128 margin-top: 1.5em;
129 margin-bottom: 1.5em;
130}
131div.imageblock, div.exampleblock, div.verseblock,
132div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
133div.admonitionblock {
134 margin-top: 1.0em;
135 margin-bottom: 1.5em;
136}
137div.admonitionblock {
138 margin-top: 2.0em;
139 margin-bottom: 2.0em;
140 margin-right: 10%;
141 color: #606060;
142}
143
144div.content { /* Block element content. */
145 padding: 0;
146}
147
148/* Block element titles. */
149div.title, caption.title {
150 color: #527bbd;
151 font-weight: bold;
152 text-align: left;
153 margin-top: 1.0em;
154 margin-bottom: 0.5em;
155}
156div.title + * {
157 margin-top: 0;
158}
159
160td div.title:first-child {
161 margin-top: 0.0em;
162}
163div.content div.title:first-child {
164 margin-top: 0.0em;
165}
166div.content + div.title {
167 margin-top: 0.0em;
168}
169
170div.sidebarblock > div.content {
171 background: #ffffee;
172 border: 1px solid #dddddd;
173 border-left: 4px solid #f0f0f0;
174 padding: 0.5em;
175}
176
177div.listingblock > div.content {
178 border: 1px solid #dddddd;
179 border-left: 5px solid #f0f0f0;
180 background: #f8f8f8;
181 padding: 0.5em;
182}
183
184div.quoteblock, div.verseblock {
185 padding-left: 1.0em;
186 margin-left: 1.0em;
187 margin-right: 10%;
188 border-left: 5px solid #f0f0f0;
189 color: #888;
190}
191
192div.quoteblock > div.attribution {
193 padding-top: 0.5em;
194 text-align: right;
195}
196
197div.verseblock > pre.content {
198 font-family: inherit;
199 font-size: inherit;
200}
201div.verseblock > div.attribution {
202 padding-top: 0.75em;
203 text-align: left;
204}
205/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
206div.verseblock + div.attribution {
207 text-align: left;
208}
209
210div.admonitionblock .icon {
211 vertical-align: top;
212 font-size: 1.1em;
213 font-weight: bold;
214 text-decoration: underline;
215 color: #527bbd;
216 padding-right: 0.5em;
217}
218div.admonitionblock td.content {
219 padding-left: 0.5em;
220 border-left: 3px solid #dddddd;
221}
222
223div.exampleblock > div.content {
224 border-left: 3px solid #dddddd;
225 padding-left: 0.5em;
226}
227
228div.imageblock div.content { padding-left: 0; }
229span.image img { border-style: none; vertical-align: text-bottom; }
230a.image:visited { color: white; }
231
232dl {
233 margin-top: 0.8em;
234 margin-bottom: 0.8em;
235}
236dt {
237 margin-top: 0.5em;
238 margin-bottom: 0;
239 font-style: normal;
240 color: navy;
241}
242dd > *:first-child {
243 margin-top: 0.1em;
244}
245
246ul, ol {
247 list-style-position: outside;
248}
249ol.arabic {
250 list-style-type: decimal;
251}
252ol.loweralpha {
253 list-style-type: lower-alpha;
254}
255ol.upperalpha {
256 list-style-type: upper-alpha;
257}
258ol.lowerroman {
259 list-style-type: lower-roman;
260}
261ol.upperroman {
262 list-style-type: upper-roman;
263}
264
265div.compact ul, div.compact ol,
266div.compact p, div.compact p,
267div.compact div, div.compact div {
268 margin-top: 0.1em;
269 margin-bottom: 0.1em;
270}
271
272tfoot {
273 font-weight: bold;
274}
275td > div.verse {
276 white-space: pre;
277}
278
279div.hdlist {
280 margin-top: 0.8em;
281 margin-bottom: 0.8em;
282}
283div.hdlist tr {
284 padding-bottom: 15px;
285}
286dt.hdlist1.strong, td.hdlist1.strong {
287 font-weight: bold;
288}
289td.hdlist1 {
290 vertical-align: top;
291 font-style: normal;
292 padding-right: 0.8em;
293 color: navy;
294}
295td.hdlist2 {
296 vertical-align: top;
297}
298div.hdlist.compact tr {
299 margin: 0;
300 padding-bottom: 0;
301}
302
303.comment {
304 background: yellow;
305}
306
307.footnote, .footnoteref {
308 font-size: 0.8em;
309}
310
311span.footnote, span.footnoteref {
312 vertical-align: super;
313}
314
315#footnotes {
316 margin: 20px 0 20px 0;
317 padding: 7px 0 0 0;
318}
319
320#footnotes div.footnote {
321 margin: 0 0 5px 0;
322}
323
324#footnotes hr {
325 border: none;
326 border-top: 1px solid silver;
327 height: 1px;
328 text-align: left;
329 margin-left: 0;
330 width: 20%;
331 min-width: 100px;
332}
333
334div.colist td {
335 padding-right: 0.5em;
336 padding-bottom: 0.3em;
337 vertical-align: top;
338}
339div.colist td img {
340 margin-top: 0.3em;
341}
342
343@media print {
344 #footer-badges { display: none; }
345}
346
347#toc {
348 margin-bottom: 2.5em;
349}
350
351#toctitle {
352 color: #527bbd;
353 font-size: 1.1em;
354 font-weight: bold;
355 margin-top: 1.0em;
356 margin-bottom: 0.1em;
357}
358
359div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
360 margin-top: 0;
361 margin-bottom: 0;
362}
363div.toclevel2 {
364 margin-left: 2em;
365 font-size: 0.9em;
366}
367div.toclevel3 {
368 margin-left: 4em;
369 font-size: 0.9em;
370}
371div.toclevel4 {
372 margin-left: 6em;
373 font-size: 0.9em;
374}
375
376span.aqua { color: aqua; }
377span.black { color: black; }
378span.blue { color: blue; }
379span.fuchsia { color: fuchsia; }
380span.gray { color: gray; }
381span.green { color: green; }
382span.lime { color: lime; }
383span.maroon { color: maroon; }
384span.navy { color: navy; }
385span.olive { color: olive; }
386span.purple { color: purple; }
387span.red { color: red; }
388span.silver { color: silver; }
389span.teal { color: teal; }
390span.white { color: white; }
391span.yellow { color: yellow; }
392
393span.aqua-background { background: aqua; }
394span.black-background { background: black; }
395span.blue-background { background: blue; }
396span.fuchsia-background { background: fuchsia; }
397span.gray-background { background: gray; }
398span.green-background { background: green; }
399span.lime-background { background: lime; }
400span.maroon-background { background: maroon; }
401span.navy-background { background: navy; }
402span.olive-background { background: olive; }
403span.purple-background { background: purple; }
404span.red-background { background: red; }
405span.silver-background { background: silver; }
406span.teal-background { background: teal; }
407span.white-background { background: white; }
408span.yellow-background { background: yellow; }
409
410span.big { font-size: 2em; }
411span.small { font-size: 0.6em; }
412
413span.underline { text-decoration: underline; }
414span.overline { text-decoration: overline; }
415span.line-through { text-decoration: line-through; }
416
417div.unbreakable { page-break-inside: avoid; }
418
419
420/*
421 * xhtml11 specific
422 *
423 * */
424
425div.tableblock {
426 margin-top: 1.0em;
427 margin-bottom: 1.5em;
428}
429div.tableblock > table {
430 border: 3px solid #527bbd;
431}
432thead, p.table.header {
433 font-weight: bold;
434 color: #527bbd;
435}
436p.table {
437 margin-top: 0;
438}
439/* Because the table frame attribute is overriden by CSS in most browsers. */
440div.tableblock > table[frame="void"] {
441 border-style: none;
442}
443div.tableblock > table[frame="hsides"] {
444 border-left-style: none;
445 border-right-style: none;
446}
447div.tableblock > table[frame="vsides"] {
448 border-top-style: none;
449 border-bottom-style: none;
450}
451
452
453/*
454 * html5 specific
455 *
456 * */
457
458table.tableblock {
459 margin-top: 1.0em;
460 margin-bottom: 1.5em;
461}
462thead, p.tableblock.header {
463 font-weight: bold;
464 color: #527bbd;
465}
466p.tableblock {
467 margin-top: 0;
468}
469table.tableblock {
470 border-width: 3px;
471 border-spacing: 0px;
472 border-style: solid;
473 border-color: #527bbd;
474 border-collapse: collapse;
475}
476th.tableblock, td.tableblock {
477 border-width: 1px;
478 padding: 4px;
479 border-style: solid;
480 border-color: #527bbd;
481}
482
483table.tableblock.frame-topbot {
484 border-left-style: hidden;
485 border-right-style: hidden;
486}
487table.tableblock.frame-sides {
488 border-top-style: hidden;
489 border-bottom-style: hidden;
490}
491table.tableblock.frame-none {
492 border-style: hidden;
493}
494
495th.tableblock.halign-left, td.tableblock.halign-left {
496 text-align: left;
497}
498th.tableblock.halign-center, td.tableblock.halign-center {
499 text-align: center;
500}
501th.tableblock.halign-right, td.tableblock.halign-right {
502 text-align: right;
503}
504
505th.tableblock.valign-top, td.tableblock.valign-top {
506 vertical-align: top;
507}
508th.tableblock.valign-middle, td.tableblock.valign-middle {
509 vertical-align: middle;
510}
511th.tableblock.valign-bottom, td.tableblock.valign-bottom {
512 vertical-align: bottom;
513}
514
515
516/*
517 * manpage specific
518 *
519 * */
520
521body.manpage h1 {
522 padding-top: 0.5em;
523 padding-bottom: 0.5em;
524 border-top: 2px solid silver;
525 border-bottom: 2px solid silver;
526}
527body.manpage h2 {
528 border-style: none;
529}
530body.manpage div.sectionbody {
531 margin-left: 3em;
532}
533
534@media print {
535 body.manpage div#toc { display: none; }
536}
537
538
539</style>
540<script type="text/javascript">
541/*<![CDATA[*/
542var asciidoc = { // Namespace.
543
544/////////////////////////////////////////////////////////////////////
545// Table Of Contents generator
546/////////////////////////////////////////////////////////////////////
547
548/* Author: Mihai Bazon, September 2002
549 * http://students.infoiasi.ro/~mishoo
550 *
551 * Table Of Content generator
552 * Version: 0.4
553 *
554 * Feel free to use this script under the terms of the GNU General Public
555 * License, as long as you do not remove or alter this notice.
556 */
557
558 /* modified by Troy D. Hanson, September 2006. License: GPL */
559 /* modified by Stuart Rackham, 2006, 2009. License: GPL */
560
561// toclevels = 1..4.
562toc: function (toclevels) {
563
564 function getText(el) {
565 var text = "";
566 for (var i = el.firstChild; i != null; i = i.nextSibling) {
567 if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
568 text += i.data;
569 else if (i.firstChild != null)
570 text += getText(i);
571 }
572 return text;
573 }
574
575 function TocEntry(el, text, toclevel) {
576 this.element = el;
577 this.text = text;
578 this.toclevel = toclevel;
579 }
580
581 function tocEntries(el, toclevels) {
582 var result = new Array;
583 var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
584 // Function that scans the DOM tree for header elements (the DOM2
585 // nodeIterator API would be a better technique but not supported by all
586 // browsers).
587 var iterate = function (el) {
588 for (var i = el.firstChild; i != null; i = i.nextSibling) {
589 if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
590 var mo = re.exec(i.tagName);
591 if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
592 result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
593 }
594 iterate(i);
595 }
596 }
597 }
598 iterate(el);
599 return result;
600 }
601
602 var toc = document.getElementById("toc");
603 if (!toc) {
604 return;
605 }
606
607 // Delete existing TOC entries in case we're reloading the TOC.
608 var tocEntriesToRemove = [];
609 var i;
610 for (i = 0; i < toc.childNodes.length; i++) {
611 var entry = toc.childNodes[i];
612 if (entry.nodeName.toLowerCase() == 'div'
613 && entry.getAttribute("class")
614 && entry.getAttribute("class").match(/^toclevel/))
615 tocEntriesToRemove.push(entry);
616 }
617 for (i = 0; i < tocEntriesToRemove.length; i++) {
618 toc.removeChild(tocEntriesToRemove[i]);
619 }
620
621 // Rebuild TOC entries.
622 var entries = tocEntries(document.getElementById("content"), toclevels);
623 for (var i = 0; i < entries.length; ++i) {
624 var entry = entries[i];
625 if (entry.element.id == "")
626 entry.element.id = "_toc_" + i;
627 var a = document.createElement("a");
628 a.href = "#" + entry.element.id;
629 a.appendChild(document.createTextNode(entry.text));
630 var div = document.createElement("div");
631 div.appendChild(a);
632 div.className = "toclevel" + entry.toclevel;
633 toc.appendChild(div);
634 }
635 if (entries.length == 0)
636 toc.parentNode.removeChild(toc);
637},
638
639
640/////////////////////////////////////////////////////////////////////
641// Footnotes generator
642/////////////////////////////////////////////////////////////////////
643
644/* Based on footnote generation code from:
645 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
646 */
647
648footnotes: function () {
649 // Delete existing footnote entries in case we're reloading the footnodes.
650 var i;
651 var noteholder = document.getElementById("footnotes");
652 if (!noteholder) {
653 return;
654 }
655 var entriesToRemove = [];
656 for (i = 0; i < noteholder.childNodes.length; i++) {
657 var entry = noteholder.childNodes[i];
658 if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
659 entriesToRemove.push(entry);
660 }
661 for (i = 0; i < entriesToRemove.length; i++) {
662 noteholder.removeChild(entriesToRemove[i]);
663 }
664
665 // Rebuild footnote entries.
666 var cont = document.getElementById("content");
667 var spans = cont.getElementsByTagName("span");
668 var refs = {};
669 var n = 0;
670 for (i=0; i<spans.length; i++) {
671 if (spans[i].className == "footnote") {
672 n++;
673 var note = spans[i].getAttribute("data-note");
674 if (!note) {
675 // Use [\s\S] in place of . so multi-line matches work.
676 // Because JavaScript has no s (dotall) regex flag.
677 note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
678 spans[i].innerHTML =
679 "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
680 "' title='View footnote' class='footnote'>" + n + "</a>]";
681 spans[i].setAttribute("data-note", note);
682 }
683 noteholder.innerHTML +=
684 "<div class='footnote' id='_footnote_" + n + "'>" +
685 "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
686 n + "</a>. " + note + "</div>";
687 var id =spans[i].getAttribute("id");
688 if (id != null) refs["#"+id] = n;
689 }
690 }
691 if (n == 0)
692 noteholder.parentNode.removeChild(noteholder);
693 else {
694 // Process footnoterefs.
695 for (i=0; i<spans.length; i++) {
696 if (spans[i].className == "footnoteref") {
697 var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
698 href = href.match(/#.*/)[0]; // Because IE return full URL.
699 n = refs[href];
700 spans[i].innerHTML =
701 "[<a href='#_footnote_" + n +
702 "' title='View footnote' class='footnote'>" + n + "</a>]";
703 }
704 }
705 }
706},
707
708install: function(toclevels) {
709 var timerId;
710
711 function reinstall() {
712 asciidoc.footnotes();
713 if (toclevels) {
714 asciidoc.toc(toclevels);
715 }
716 }
717
718 function reinstallAndRemoveTimer() {
719 clearInterval(timerId);
720 reinstall();
721 }
722
723 timerId = setInterval(reinstall, 500);
724 if (document.addEventListener)
725 document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
726 else
727 window.onload = reinstallAndRemoveTimer;
728}
729
730}
731asciidoc.install();
732/*]]>*/
733</script>
734</head>
735<body class="article">
736<div id="header">
737<h1>Trace2 API</h1>
738</div>
739<div id="content">
740<div id="preamble">
741<div class="sectionbody">
742<div class="paragraph"><p>The Trace2 API can be used to print debug, performance, and telemetry
743information to stderr or a file. The Trace2 feature is inactive unless
744explicitly enabled by enabling one or more Trace2 Targets.</p></div>
745<div class="paragraph"><p>The Trace2 API is intended to replace the existing (Trace1)
746printf-style tracing provided by the existing <code>GIT_TRACE</code> and
747<code>GIT_TRACE_PERFORMANCE</code> facilities. During initial implementation,
748Trace2 and Trace1 may operate in parallel.</p></div>
749<div class="paragraph"><p>The Trace2 API defines a set of high-level messages with known fields,
750such as (<code>start</code>: <code>argv</code>) and (<code>exit</code>: {<code>exit-code</code>, <code>elapsed-time</code>}).</p></div>
751<div class="paragraph"><p>Trace2 instrumentation throughout the Git code base sends Trace2
752messages to the enabled Trace2 Targets. Targets transform these
753messages content into purpose-specific formats and write events to
754their data streams. In this manner, the Trace2 API can drive
755many different types of analysis.</p></div>
756<div class="paragraph"><p>Targets are defined using a VTable allowing easy extension to other
757formats in the future. This might be used to define a binary format,
758for example.</p></div>
Junio C Hamano792b6092019-05-13 16:03:59759<div class="paragraph"><p>Trace2 is controlled using <code>trace2.*</code> config values in the system and
Junio C Hamanoc01eecf2019-05-30 18:17:47760global config files and <code>GIT_TRACE2*</code> environment variables. Trace2 does
Junio C Hamano792b6092019-05-13 16:03:59761not read from repo local or worktree config files or respect <code>-c</code>
762command line config settings.</p></div>
Junio C Hamano11f15372019-03-07 03:17:00763</div>
764</div>
765<div class="sect1">
766<h2 id="_trace2_targets">Trace2 Targets</h2>
767<div class="sectionbody">
768<div class="paragraph"><p>Trace2 defines the following set of Trace2 Targets.
769Format details are given in a later section.</p></div>
Junio C Hamano792b6092019-05-13 16:03:59770<div class="sect2">
771<h3 id="_the_normal_format_target">The Normal Format Target</h3>
772<div class="paragraph"><p>The normal format target is a tradition printf format and similar
773to GIT_TRACE format. This format is enabled with the <code>GIT_TR</code>
774environment variable or the <code>trace2.normalTarget</code> system or global
775config setting.</p></div>
776<div class="paragraph"><p>For example</p></div>
Junio C Hamano11f15372019-03-07 03:17:00777<div class="listingblock">
778<div class="content">
Junio C Hamanoc01eecf2019-05-30 18:17:47779<pre><code>$ export GIT_TRACE2=~/log.normal
Junio C Hamano11f15372019-03-07 03:17:00780$ git version
781git version 2.20.1.155.g426c96fcdb</code></pre>
782</div></div>
Junio C Hamano792b6092019-05-13 16:03:59783<div class="paragraph"><p>or</p></div>
784<div class="listingblock">
785<div class="content">
786<pre><code>$ git config --global trace2.normalTarget ~/log.normal
787$ git version
788git version 2.20.1.155.g426c96fcdb</code></pre>
789</div></div>
790<div class="paragraph"><p>yields</p></div>
Junio C Hamano11f15372019-03-07 03:17:00791<div class="listingblock">
792<div class="content">
793<pre><code>$ cat ~/log.normal
79412:28:42.620009 common-main.c:38 version 2.20.1.155.g426c96fcdb
79512:28:42.620989 common-main.c:39 start git version
79612:28:42.621101 git.c:432 cmd_name version (version)
79712:28:42.621215 git.c:662 exit elapsed:0.001227 code:0
79812:28:42.621250 trace2/tr2_tgt_normal.c:124 atexit elapsed:0.001265 code:0</code></pre>
799</div></div>
Junio C Hamano792b6092019-05-13 16:03:59800</div>
801<div class="sect2">
802<h3 id="_the_performance_format_target">The Performance Format Target</h3>
803<div class="paragraph"><p>The performance format target (PERF) is a column-based format to
804replace GIT_TRACE_PERFORMANCE and is suitable for development and
805testing, possibly to complement tools like gprof. This format is
Junio C Hamanoc01eecf2019-05-30 18:17:47806enabled with the <code>GIT_TRACE2_PERF</code> environment variable or the
Junio C Hamano792b6092019-05-13 16:03:59807<code>trace2.perfTarget</code> system or global config setting.</p></div>
808<div class="paragraph"><p>For example</p></div>
Junio C Hamano11f15372019-03-07 03:17:00809<div class="listingblock">
810<div class="content">
Junio C Hamanoc01eecf2019-05-30 18:17:47811<pre><code>$ export GIT_TRACE2_PERF=~/log.perf
Junio C Hamano11f15372019-03-07 03:17:00812$ git version
813git version 2.20.1.155.g426c96fcdb</code></pre>
814</div></div>
Junio C Hamano792b6092019-05-13 16:03:59815<div class="paragraph"><p>or</p></div>
816<div class="listingblock">
817<div class="content">
818<pre><code>$ git config --global trace2.perfTarget ~/log.perf
819$ git version
820git version 2.20.1.155.g426c96fcdb</code></pre>
821</div></div>
822<div class="paragraph"><p>yields</p></div>
Junio C Hamano11f15372019-03-07 03:17:00823<div class="listingblock">
824<div class="content">
825<pre><code>$ cat ~/log.perf
82612:28:42.620675 common-main.c:38 | d0 | main | version | | | | | 2.20.1.155.g426c96fcdb
Junio C Hamano792b6092019-05-13 16:03:5982712:28:42.621001 common-main.c:39 | d0 | main | start | | 0.001173 | | | git version
Junio C Hamano11f15372019-03-07 03:17:0082812:28:42.621111 git.c:432 | d0 | main | cmd_name | | | | | version (version)
82912:28:42.621225 git.c:662 | d0 | main | exit | | 0.001227 | | | code:0
83012:28:42.621259 trace2/tr2_tgt_perf.c:211 | d0 | main | atexit | | 0.001265 | | | code:0</code></pre>
831</div></div>
Junio C Hamano792b6092019-05-13 16:03:59832</div>
833<div class="sect2">
834<h3 id="_the_event_format_target">The Event Format Target</h3>
835<div class="paragraph"><p>The event format target is a JSON-based format of event data suitable
Junio C Hamanoc01eecf2019-05-30 18:17:47836for telemetry analysis. This format is enabled with the <code>GIT_TRACE2_EVENT</code>
Junio C Hamano792b6092019-05-13 16:03:59837environment variable or the <code>trace2.eventTarget</code> system or global config
838setting.</p></div>
839<div class="paragraph"><p>For example</p></div>
Junio C Hamano11f15372019-03-07 03:17:00840<div class="listingblock">
841<div class="content">
Junio C Hamanoc01eecf2019-05-30 18:17:47842<pre><code>$ export GIT_TRACE2_EVENT=~/log.event
Junio C Hamano11f15372019-03-07 03:17:00843$ git version
844git version 2.20.1.155.g426c96fcdb</code></pre>
845</div></div>
Junio C Hamano792b6092019-05-13 16:03:59846<div class="paragraph"><p>or</p></div>
847<div class="listingblock">
848<div class="content">
849<pre><code>$ git config --global trace2.eventTarget ~/log.event
850$ git version
851git version 2.20.1.155.g426c96fcdb</code></pre>
852</div></div>
853<div class="paragraph"><p>yields</p></div>
Junio C Hamano11f15372019-03-07 03:17:00854<div class="listingblock">
855<div class="content">
856<pre><code>$ cat ~/log.event
Junio C Hamano792b6092019-05-13 16:03:59857{"event":"version","sid":"sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.620713Z","file":"common-main.c","line":38,"evt":"1","exe":"2.20.1.155.g426c96fcdb"}
858{"event":"start","sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.621027Z","file":"common-main.c","line":39,"t_abs":0.001173,"argv":["git","version"]}
859{"event":"cmd_name","sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.621122Z","file":"git.c","line":432,"name":"version","hierarchy":"version"}
860{"event":"exit","sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.621236Z","file":"git.c","line":662,"t_abs":0.001227,"code":0}
861{"event":"atexit","sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.621268Z","file":"trace2/tr2_tgt_event.c","line":163,"t_abs":0.001265,"code":0}</code></pre>
Junio C Hamano11f15372019-03-07 03:17:00862</div></div>
Junio C Hamano11f15372019-03-07 03:17:00863</div>
Junio C Hamano792b6092019-05-13 16:03:59864<div class="sect2">
865<h3 id="_enabling_a_target">Enabling a Target</h3>
866<div class="paragraph"><p>To enable a target, set the corresponding environment variable or
867system or global config value to one of the following:</p></div>
868<div class="openblock">
Junio C Hamanod1063b12019-05-08 17:18:07869<div class="content">
Junio C Hamano792b6092019-05-13 16:03:59870<div class="ulist"><ul>
871<li>
872<p>
873<code>0</code> or <code>false</code> - Disables the target.
874</p>
875</li>
876<li>
877<p>
878<code>1</code> or <code>true</code> - Writes to <code>STDERR</code>.
879</p>
880</li>
881<li>
882<p>
883<code>[2-9]</code> - Writes to the already opened file descriptor.
884</p>
885</li>
886<li>
887<p>
888<code>&lt;absolute-pathname&gt;</code> - Writes to the file in append mode.
889</p>
890</li>
891<li>
892<p>
893<code>af_unix:[&lt;socket_type&gt;:]&lt;absolute-pathname&gt;</code> - Write to a
894Unix DomainSocket (on platforms that support them). Socket
895type can be either <code>stream</code> or <code>dgram</code>; if omitted Git will
896try both.
897</p>
898</li>
899</ul></div>
900</div></div>
901<div class="paragraph"><p>If the target already exists and is a directory, the traces will be
Junio C Hamanod1063b12019-05-08 17:18:07902written to files (one per process) underneath the given directory. They
903will be named according to the last component of the SID (optionally
Junio C Hamano792b6092019-05-13 16:03:59904followed by a counter to avoid filename collisions).</p></div>
905</div>
Junio C Hamano11f15372019-03-07 03:17:00906</div>
907</div>
908<div class="sect1">
909<h2 id="_trace2_api">Trace2 API</h2>
910<div class="sectionbody">
911<div class="paragraph"><p>All public Trace2 functions and macros are defined in <code>trace2.h</code> and
912<code>trace2.c</code>. All public symbols are prefixed with <code>trace2_</code>.</p></div>
913<div class="paragraph"><p>There are no public Trace2 data structures.</p></div>
914<div class="paragraph"><p>The Trace2 code also defines a set of private functions and data types
915in the <code>trace2/</code> directory. These symbols are prefixed with <code>tr2_</code>
916and should only be used by functions in <code>trace2.c</code>.</p></div>
917</div>
918</div>
919<div class="sect1">
920<h2 id="_conventions_for_public_functions_and_macros">Conventions for Public Functions and Macros</h2>
921<div class="sectionbody">
922<div class="paragraph"><p>The functions defined by the Trace2 API are declared and documented
923in <code>trace2.h</code>. It defines the API functions and wrapper macros for
924Trace2.</p></div>
925<div class="paragraph"><p>Some functions have a <code>_fl()</code> suffix to indicate that they take <code>file</code>
926and <code>line-number</code> arguments.</p></div>
927<div class="paragraph"><p>Some functions have a <code>_va_fl()</code> suffix to indicate that they also
928take a <code>va_list</code> argument.</p></div>
929<div class="paragraph"><p>Some functions have a <code>_printf_fl()</code> suffix to indicate that they also
930take a varargs argument.</p></div>
931<div class="paragraph"><p>There are CPP wrapper macros and ifdefs to hide most of these details.
932See <code>trace2.h</code> for more details. The following discussion will only
933describe the simplified forms.</p></div>
934</div>
935</div>
936<div class="sect1">
937<h2 id="_public_api">Public API</h2>
938<div class="sectionbody">
939<div class="paragraph"><p>All Trace2 API functions send a messsage to all of the active
940Trace2 Targets. This section describes the set of available
941messages.</p></div>
942<div class="paragraph"><p>It helps to divide these functions into groups for discussion
943purposes.</p></div>
944<div class="sect2">
945<h3 id="_basic_command_messages">Basic Command Messages</h3>
946<div class="paragraph"><p>These are concerned with the lifetime of the overall git process.</p></div>
947<div class="dlist"><dl>
948<dt class="hdlist1">
Junio C Hamano792b6092019-05-13 16:03:59949<code>void trace2_initialize_clock()</code>
950</dt>
951<dd>
952<p>
953 Initialize the Trace2 start clock and nothing else. This should
954 be called at the very top of main() to capture the process start
955 time and reduce startup order dependencies.
956</p>
957</dd>
958<dt class="hdlist1">
Junio C Hamano11f15372019-03-07 03:17:00959<code>void trace2_initialize()</code>
960</dt>
961<dd>
962<p>
963 Determines if any Trace2 Targets should be enabled and
Junio C Hamano792b6092019-05-13 16:03:59964 initializes the Trace2 facility. This includes setting up the
965 Trace2 thread local storage (TLS).
Junio C Hamano11f15372019-03-07 03:17:00966</p>
967<div class="paragraph"><p>This function emits a "version" message containing the version of git
968and the Trace2 protocol.</p></div>
969<div class="paragraph"><p>This function should be called from <code>main()</code> as early as possible in
Junio C Hamano792b6092019-05-13 16:03:59970the life of the process after essential process initialization.</p></div>
Junio C Hamano11f15372019-03-07 03:17:00971</dd>
972<dt class="hdlist1">
973<code>int trace2_is_enabled()</code>
974</dt>
975<dd>
976<p>
977 Returns 1 if Trace2 is enabled (at least one target is
978 active).
979</p>
980</dd>
981<dt class="hdlist1">
982<code>void trace2_cmd_start(int argc, const char **argv)</code>
983</dt>
984<dd>
985<p>
986 Emits a "start" message containing the process command line
987 arguments.
988</p>
989</dd>
990<dt class="hdlist1">
991<code>int trace2_cmd_exit(int exit_code)</code>
992</dt>
993<dd>
994<p>
995 Emits an "exit" message containing the process exit-code and
996 elapsed time.
997</p>
998<div class="paragraph"><p>Returns the exit-code.</p></div>
999</dd>
1000<dt class="hdlist1">
1001<code>void trace2_cmd_error(const char *fmt, va_list ap)</code>
1002</dt>
1003<dd>
1004<p>
1005 Emits an "error" message containing a formatted error message.
1006</p>
1007</dd>
1008<dt class="hdlist1">
1009<code>void trace2_cmd_path(const char *pathname)</code>
1010</dt>
1011<dd>
1012<p>
1013 Emits a "cmd_path" message with the full pathname of the
1014 current process.
1015</p>
1016</dd>
1017</dl></div>
1018</div>
1019<div class="sect2">
1020<h3 id="_command_detail_messages">Command Detail Messages</h3>
1021<div class="paragraph"><p>These are concerned with describing the specific Git command
1022after the command line, config, and environment are inspected.</p></div>
1023<div class="dlist"><dl>
1024<dt class="hdlist1">
1025<code>void trace2_cmd_name(const char *name)</code>
1026</dt>
1027<dd>
1028<p>
1029 Emits a "cmd_name" message with the canonical name of the
1030 command, for example "status" or "checkout".
1031</p>
1032</dd>
1033<dt class="hdlist1">
1034<code>void trace2_cmd_mode(const char *mode)</code>
1035</dt>
1036<dd>
1037<p>
1038 Emits a "cmd_mode" message with a qualifier name to further
1039 describe the current git command.
1040</p>
1041<div class="paragraph"><p>This message is intended to be used with git commands having multiple
1042major modes. For example, a "checkout" command can checkout a new
1043branch or it can checkout a single file, so the checkout code could
1044emit a cmd_mode message of "branch" or "file".</p></div>
1045</dd>
1046<dt class="hdlist1">
1047<code>void trace2_cmd_alias(const char *alias, const char **argv_expansion)</code>
1048</dt>
1049<dd>
1050<p>
1051 Emits an "alias" message containing the alias used and the
1052 argument expansion.
1053</p>
1054</dd>
1055<dt class="hdlist1">
1056<code>void trace2_def_param(const char *parameter, const char *value)</code>
1057</dt>
1058<dd>
1059<p>
1060 Emits a "def_param" message containing a key/value pair.
1061</p>
1062<div class="paragraph"><p>This message is intended to report some global aspect of the current
1063command, such as a configuration setting or command line switch that
1064significantly affects program performance or behavior, such as
1065<code>core.abbrev</code>, <code>status.showUntrackedFiles</code>, or <code>--no-ahead-behind</code>.</p></div>
1066</dd>
1067<dt class="hdlist1">
1068<code>void trace2_cmd_list_config()</code>
1069</dt>
1070<dd>
1071<p>
1072 Emits a "def_param" messages for "important" configuration
1073 settings.
1074</p>
Junio C Hamanoc01eecf2019-05-30 18:17:471075<div class="paragraph"><p>The environment variable <code>GIT_TRACE2_CONFIG_PARAMS</code> or the <code>trace2.configParams</code>
Junio C Hamano792b6092019-05-13 16:03:591076config value can be set to a
Junio C Hamano11f15372019-03-07 03:17:001077list of patterns of important configuration settings, for example:
1078<code>core.*,remote.*.url</code>. This function will iterate over all config
1079settings and emit a "def_param" message for each match.</p></div>
1080</dd>
1081<dt class="hdlist1">
1082<code>void trace2_cmd_set_config(const char *key, const char *value)</code>
1083</dt>
1084<dd>
1085<p>
Junio C Hamano792b6092019-05-13 16:03:591086 Emits a "def_param" message for a new or updated key/value
1087 pair IF <code>key</code> is considered important.
Junio C Hamano11f15372019-03-07 03:17:001088</p>
1089<div class="paragraph"><p>This is used to hook into <code>git_config_set()</code> and catch any
1090configuration changes and update a value previously reported by
1091<code>trace2_cmd_list_config()</code>.</p></div>
1092</dd>
1093<dt class="hdlist1">
1094<code>void trace2_def_repo(struct repository *repo)</code>
1095</dt>
1096<dd>
1097<p>
1098 Registers a repository with the Trace2 layer. Assigns a
1099 unique "repo-id" to <code>repo-&gt;trace2_repo_id</code>.
1100</p>
1101<div class="paragraph"><p>Emits a "worktree" messages containing the repo-id and the worktree
1102pathname.</p></div>
1103<div class="paragraph"><p>Region and data messages (described later) may refer to this repo-id.</p></div>
1104<div class="paragraph"><p>The main/top-level repository will have repo-id value 1 (aka "r1").</p></div>
1105<div class="paragraph"><p>The repo-id field is in anticipation of future in-proc submodule
1106repositories.</p></div>
1107</dd>
1108</dl></div>
1109</div>
1110<div class="sect2">
1111<h3 id="_child_process_messages">Child Process Messages</h3>
1112<div class="paragraph"><p>These are concerned with the various spawned child processes,
1113including shell scripts, git commands, editors, pagers, and hooks.</p></div>
1114<div class="dlist"><dl>
1115<dt class="hdlist1">
1116<code>void trace2_child_start(struct child_process *cmd)</code>
1117</dt>
1118<dd>
1119<p>
1120 Emits a "child_start" message containing the "child-id",
1121 "child-argv", and "child-classification".
1122</p>
1123<div class="paragraph"><p>Before calling this, set <code>cmd-&gt;trace2_child_class</code> to a name
1124describing the type of child process, for example "editor".</p></div>
1125<div class="paragraph"><p>This function assigns a unique "child-id" to <code>cmd-&gt;trace2_child_id</code>.
1126This field is used later during the "child_exit" message to associate
1127it with the "child_start" message.</p></div>
1128<div class="paragraph"><p>This function should be called before spawning the child process.</p></div>
1129</dd>
1130<dt class="hdlist1">
1131<code>void trace2_child_exit(struct child_proess *cmd, int child_exit_code)</code>
1132</dt>
1133<dd>
1134<p>
1135 Emits a "child_exit" message containing the "child-id",
1136 the child&#8217;s elapsed time and exit-code.
1137</p>
1138<div class="paragraph"><p>The reported elapsed time includes the process creation overhead and
1139time spend waiting for it to exit, so it may be slightly longer than
1140the time reported by the child itself.</p></div>
1141<div class="paragraph"><p>This function should be called after reaping the child process.</p></div>
1142</dd>
1143<dt class="hdlist1">
1144<code>int trace2_exec(const char *exe, const char **argv)</code>
1145</dt>
1146<dd>
1147<p>
1148 Emits a "exec" message containing the "exec-id" and the
1149 argv of the new process.
1150</p>
1151<div class="paragraph"><p>This function should be called before calling one of the <code>exec()</code>
1152variants, such as <code>execvp()</code>.</p></div>
1153<div class="paragraph"><p>This function returns a unique "exec-id". This value is used later
1154if the exec() fails and a "exec-result" message is necessary.</p></div>
1155</dd>
1156<dt class="hdlist1">
1157<code>void trace2_exec_result(int exec_id, int error_code)</code>
1158</dt>
1159<dd>
1160<p>
1161 Emits a "exec_result" message containing the "exec-id"
1162 and the error code.
1163</p>
1164<div class="paragraph"><p>On Unix-based systems, <code>exec()</code> does not return if successful.
1165This message is used to indicate that the <code>exec()</code> failed and
1166that the current program is continuing.</p></div>
1167</dd>
1168</dl></div>
1169</div>
1170<div class="sect2">
1171<h3 id="_git_thread_messages">Git Thread Messages</h3>
1172<div class="paragraph"><p>These messages are concerned with Git thread usage.</p></div>
1173<div class="dlist"><dl>
1174<dt class="hdlist1">
1175<code>void trace2_thread_start(const char *thread_name)</code>
1176</dt>
1177<dd>
1178<p>
1179 Emits a "thread_start" message.
1180</p>
1181<div class="paragraph"><p>The <code>thread_name</code> field should be a descriptive name, such as the
1182unique name of the thread-proc. A unique "thread-id" will be added
1183to the name to uniquely identify thread instances.</p></div>
1184<div class="paragraph"><p>Region and data messages (described later) may refer to this thread
1185name.</p></div>
1186<div class="paragraph"><p>This function must be called by the thread-proc of the new thread
1187(so that TLS data is properly initialized) and not by the caller
1188of <code>pthread_create()</code>.</p></div>
1189</dd>
1190<dt class="hdlist1">
1191<code>void trace2_thread_exit()</code>
1192</dt>
1193<dd>
1194<p>
1195 Emits a "thread_exit" message containing the thread name
1196 and the thread elapsed time.
1197</p>
1198<div class="paragraph"><p>This function must be called by the thread-proc before it returns
1199(so that the coorect TLS data is used and cleaned up. It should
1200not be called by the caller of <code>pthread_join()</code>.</p></div>
1201</dd>
1202</dl></div>
1203</div>
1204<div class="sect2">
1205<h3 id="_region_and_data_messages">Region and Data Messages</h3>
1206<div class="paragraph"><p>These are concerned with recording performance data
1207over regions or spans of code.</p></div>
1208<div class="dlist"><dl>
1209<dt class="hdlist1">
1210<code>void trace2_region_enter(const char *category, const char *label, const struct repository *repo)</code>
1211</dt>
1212<dt class="hdlist1">
1213<code>void trace2_region_enter_printf(const char *category, const char *label, const struct repository *repo, const char *fmt, ...)</code>
1214</dt>
1215<dt class="hdlist1">
1216<code>void trace2_region_enter_printf_va(const char *category, const char *label, const struct repository *repo, const char *fmt, va_list ap)</code>
1217</dt>
1218<dd>
1219<p>
1220 Emits a thread-relative "region_enter" message with optional
1221 printf string.
1222</p>
1223<div class="paragraph"><p>This function pushes a new region nesting stack level on the current
1224thread and starts a clock for the new stack frame.</p></div>
1225<div class="paragraph"><p>The <code>category</code> field is an arbitrary category name used to classify
1226regions by feature area, such as "status" or "index". At this time
1227it is only just printed along with the rest of the message. It may
1228be used in the future to filter messages.</p></div>
1229<div class="paragraph"><p>The <code>label</code> field is an arbitrary label used to describe the activity
1230being started, such as "read_recursive" or "do_read_index".</p></div>
1231<div class="paragraph"><p>The <code>repo</code> field, if set, will be used to get the "repo-id", so that
1232recursive oerations can be attributed to the correct repository.</p></div>
1233</dd>
1234<dt class="hdlist1">
1235<code>void trace2_region_leave(const char *category, const char *label, const struct repository *repo)</code>
1236</dt>
1237<dt class="hdlist1">
1238<code>void trace2_region_leave_printf(const char *category, const char *label, const struct repository *repo, const char *fmt, ...)</code>
1239</dt>
1240<dt class="hdlist1">
1241<code>void trace2_region_leave_printf_va(const char *category, const char *label, const struct repository *repo, const char *fmt, va_list ap)</code>
1242</dt>
1243<dd>
1244<p>
1245 Emits a thread-relative "region_leave" message with optional
1246 printf string.
1247</p>
1248<div class="paragraph"><p>This function pops the region nesting stack on the current thread
1249and reports the elapsed time of the stack frame.</p></div>
1250<div class="paragraph"><p>The <code>category</code>, <code>label</code>, and <code>repo</code> fields are the same as above.
1251The <code>category</code> and <code>label</code> do not need to match the correpsonding
1252"region_enter" message, but it makes the data stream easier to
1253understand.</p></div>
1254</dd>
1255<dt class="hdlist1">
1256<code>void trace2_data_string(const char *category, const struct repository *repo, const char *key, const char * value)</code>
1257</dt>
1258<dt class="hdlist1">
1259<code>void trace2_data_intmax(const char *category, const struct repository *repo, const char *key, intmax value)</code>
1260</dt>
1261<dt class="hdlist1">
1262<code>void trace2_data_json(const char *category, const struct repository *repo, const char *key, const struct json_writer *jw)</code>
1263</dt>
1264<dd>
1265<p>
1266 Emits a region- and thread-relative "data" or "data_json" message.
1267</p>
1268<div class="paragraph"><p>This is a key/value pair message containing information about the
1269current thread, region stack, and repository. This could be used
1270to print the number of files in a directory during a multi-threaded
1271recursive tree walk.</p></div>
1272</dd>
1273<dt class="hdlist1">
1274<code>void trace2_printf(const char *fmt, ...)</code>
1275</dt>
1276<dt class="hdlist1">
1277<code>void trace2_printf_va(const char *fmt, va_list ap)</code>
1278</dt>
1279<dd>
1280<p>
1281 Emits a region- and thread-relative "printf" message.
1282</p>
1283</dd>
1284</dl></div>
1285</div>
1286</div>
1287</div>
1288<div class="sect1">
1289<h2 id="_trace2_target_formats">Trace2 Target Formats</h2>
1290<div class="sectionbody">
1291<div class="sect2">
1292<h3 id="_normal_format">NORMAL Format</h3>
Junio C Hamano11f15372019-03-07 03:17:001293<div class="paragraph"><p>Events are written as lines of the form:</p></div>
1294<div class="listingblock">
1295<div class="content">
1296<pre><code>[&lt;time&gt; SP &lt;filename&gt;:&lt;line&gt; SP+] &lt;event-name&gt; [[SP] &lt;event-message&gt;] LF</code></pre>
1297</div></div>
1298<div class="dlist"><dl>
1299<dt class="hdlist1">
1300<code>&lt;event-name&gt;</code>
1301</dt>
1302<dd>
1303<p>
1304 is the event name.
1305</p>
1306</dd>
1307<dt class="hdlist1">
1308<code>&lt;event-message&gt;</code>
1309</dt>
1310<dd>
1311<p>
1312 is a free-form printf message intended for human consumption.
1313</p>
1314<div class="paragraph"><p>Note that this may contain embedded LF or CRLF characters that are
1315not escaped, so the event may spill across multiple lines.</p></div>
1316</dd>
1317</dl></div>
Junio C Hamanoc01eecf2019-05-30 18:17:471318<div class="paragraph"><p>If <code>GIT_TRACE2_BRIEF</code> or <code>trace2.normalBrief</code> is true, the <code>time</code>, <code>filename</code>,
Junio C Hamano792b6092019-05-13 16:03:591319and <code>line</code> fields are omitted.</p></div>
Junio C Hamano11f15372019-03-07 03:17:001320<div class="paragraph"><p>This target is intended to be more of a summary (like GIT_TRACE) and
1321less detailed than the other targets. It ignores thread, region, and
1322data messages, for example.</p></div>
1323</div>
1324<div class="sect2">
1325<h3 id="_perf_format">PERF Format</h3>
Junio C Hamano11f15372019-03-07 03:17:001326<div class="paragraph"><p>Events are written as lines of the form:</p></div>
1327<div class="listingblock">
1328<div class="content">
1329<pre><code>[&lt;time&gt; SP &lt;filename&gt;:&lt;line&gt; SP+
1330 BAR SP] d&lt;depth&gt; SP
1331 BAR SP &lt;thread-name&gt; SP+
1332 BAR SP &lt;event-name&gt; SP+
1333 BAR SP [r&lt;repo-id&gt;] SP+
1334 BAR SP [&lt;t_abs&gt;] SP+
1335 BAR SP [&lt;t_rel&gt;] SP+
1336 BAR SP [&lt;category&gt;] SP+
1337 BAR SP DOTS* &lt;perf-event-message&gt;
1338 LF</code></pre>
1339</div></div>
1340<div class="dlist"><dl>
1341<dt class="hdlist1">
1342<code>&lt;depth&gt;</code>
1343</dt>
1344<dd>
1345<p>
1346 is the git process depth. This is the number of parent
1347 git processes. A top-level git command has depth value "d0".
1348 A child of it has depth value "d1". A second level child
1349 has depth value "d2" and so on.
1350</p>
1351</dd>
1352<dt class="hdlist1">
1353<code>&lt;thread-name&gt;</code>
1354</dt>
1355<dd>
1356<p>
1357 is a unique name for the thread. The primary thread
1358 is called "main". Other thread names are of the form "th%d:%s"
1359 and include a unique number and the name of the thread-proc.
1360</p>
1361</dd>
1362<dt class="hdlist1">
1363<code>&lt;event-name&gt;</code>
1364</dt>
1365<dd>
1366<p>
1367 is the event name.
1368</p>
1369</dd>
1370<dt class="hdlist1">
1371<code>&lt;repo-id&gt;</code>
1372</dt>
1373<dd>
1374<p>
1375 when present, is a number indicating the repository
1376 in use. A <code>def_repo</code> event is emitted when a repository is
1377 opened. This defines the repo-id and associated worktree.
1378 Subsequent repo-specific events will reference this repo-id.
1379</p>
1380<div class="paragraph"><p>Currently, this is always "r1" for the main repository.
1381This field is in anticipation of in-proc submodules in the future.</p></div>
1382</dd>
1383<dt class="hdlist1">
1384<code>&lt;t_abs&gt;</code>
1385</dt>
1386<dd>
1387<p>
1388 when present, is the absolute time in seconds since the
1389 program started.
1390</p>
1391</dd>
1392<dt class="hdlist1">
1393<code>&lt;t_rel&gt;</code>
1394</dt>
1395<dd>
1396<p>
1397 when present, is time in seconds relative to the start of
1398 the current region. For a thread-exit event, it is the elapsed
1399 time of the thread.
1400</p>
1401</dd>
1402<dt class="hdlist1">
1403<code>&lt;category&gt;</code>
1404</dt>
1405<dd>
1406<p>
1407 is present on region and data events and is used to
1408 indicate a broad category, such as "index" or "status".
1409</p>
1410</dd>
1411<dt class="hdlist1">
1412<code>&lt;perf-event-message&gt;</code>
1413</dt>
1414<dd>
1415<p>
1416 is a free-form printf message intended for human consumption.
1417</p>
1418</dd>
1419</dl></div>
1420<div class="listingblock">
1421<div class="content">
1422<pre><code>15:33:33.532712 wt-status.c:2310 | d0 | main | region_enter | r1 | 0.126064 | | status | label:print
142315:33:33.532712 wt-status.c:2331 | d0 | main | region_leave | r1 | 0.127568 | 0.001504 | status | label:print</code></pre>
1424</div></div>
Junio C Hamanoc01eecf2019-05-30 18:17:471425<div class="paragraph"><p>If <code>GIT_TRACE2_PERF_BRIEF</code> or <code>trace2.perfBrief</code> is true, the <code>time</code>, <code>file</code>,
Junio C Hamano792b6092019-05-13 16:03:591426and <code>line</code> fields are omitted.</p></div>
Junio C Hamano11f15372019-03-07 03:17:001427<div class="listingblock">
1428<div class="content">
1429<pre><code>d0 | main | region_leave | r1 | 0.011717 | 0.009122 | index | label:preload</code></pre>
1430</div></div>
1431<div class="paragraph"><p>The PERF target is intended for interactive performance analysis
1432during development and is quite noisy.</p></div>
1433</div>
1434<div class="sect2">
1435<h3 id="_event_format">EVENT Format</h3>
Junio C Hamano11f15372019-03-07 03:17:001436<div class="paragraph"><p>Each event is a JSON-object containing multiple key/value pairs
1437written as a single line and followed by a LF.</p></div>
1438<div class="listingblock">
1439<div class="content">
1440<pre><code>'{' &lt;key&gt; ':' &lt;value&gt; [',' &lt;key&gt; ':' &lt;value&gt;]* '}' LF</code></pre>
1441</div></div>
1442<div class="paragraph"><p>Some key/value pairs are common to all events and some are
1443event-specific.</p></div>
1444<div class="sect3">
1445<h4 id="_common_key_value_pairs">Common Key/Value Pairs</h4>
1446<div class="paragraph"><p>The following key/value pairs are common to all events:</p></div>
1447<div class="listingblock">
1448<div class="content">
1449<pre><code>{
1450 "event":"version",
Junio C Hamano792b6092019-05-13 16:03:591451 "sid":"20190408T191827.272759Z-H9b68c35f-P00003510",
Junio C Hamano11f15372019-03-07 03:17:001452 "thread":"main",
Junio C Hamano792b6092019-05-13 16:03:591453 "time":"2019-04-08T19:18:27.282761Z",
Junio C Hamano11f15372019-03-07 03:17:001454 "file":"common-main.c",
Junio C Hamano792b6092019-05-13 16:03:591455 "line":42,
Junio C Hamano11f15372019-03-07 03:17:001456 ...
1457}</code></pre>
1458</div></div>
1459<div class="dlist"><dl>
1460<dt class="hdlist1">
1461<code>"event":&lt;event&gt;</code>
1462</dt>
1463<dd>
1464<p>
1465 is the event name.
1466</p>
1467</dd>
1468<dt class="hdlist1">
1469<code>"sid":&lt;sid&gt;</code>
1470</dt>
1471<dd>
1472<p>
1473 is the session-id. This is a unique string to identify the
1474 process instance to allow all events emitted by a process to
1475 be identified. A session-id is used instead of a PID because
1476 PIDs are recycled by the OS. For child git processes, the
1477 session-id is prepended with the session-id of the parent git
1478 process to allow parent-child relationships to be identified
1479 during post-processing.
1480</p>
1481</dd>
1482<dt class="hdlist1">
1483<code>"thread":&lt;thread&gt;</code>
1484</dt>
1485<dd>
1486<p>
1487 is the thread name.
1488</p>
1489</dd>
1490<dt class="hdlist1">
1491<code>"time":&lt;time&gt;</code>
1492</dt>
1493<dd>
1494<p>
1495 is the UTC time of the event.
1496</p>
1497</dd>
1498<dt class="hdlist1">
1499<code>"file":&lt;filename&gt;</code>
1500</dt>
1501<dd>
1502<p>
1503 is source file generating the event.
1504</p>
1505</dd>
1506<dt class="hdlist1">
1507<code>"line":&lt;line-number&gt;</code>
1508</dt>
1509<dd>
1510<p>
1511 is the integer source line number generating the event.
1512</p>
1513</dd>
1514<dt class="hdlist1">
1515<code>"repo":&lt;repo-id&gt;</code>
1516</dt>
1517<dd>
1518<p>
1519 when present, is the integer repo-id as described previously.
1520</p>
1521</dd>
1522</dl></div>
Junio C Hamanoc01eecf2019-05-30 18:17:471523<div class="paragraph"><p>If <code>GIT_TRACE2_EVENT_BRIEF</code> or <code>trace2.eventBrief</code> is true, the <code>file</code>
Junio C Hamano792b6092019-05-13 16:03:591524and <code>line</code> fields are omitted from all events and the <code>time</code> field is
1525only present on the "start" and "atexit" events.</p></div>
Junio C Hamano11f15372019-03-07 03:17:001526</div>
1527<div class="sect3">
1528<h4 id="_event_specific_key_value_pairs">Event-Specific Key/Value Pairs</h4>
1529<div class="dlist"><dl>
1530<dt class="hdlist1">
1531<code>"version"</code>
1532</dt>
1533<dd>
1534<p>
1535 This event gives the version of the executable and the EVENT format.
1536</p>
1537<div class="listingblock">
1538<div class="content">
1539<pre><code>{
1540 "event":"version",
1541 ...
1542 "evt":"1", # EVENT format version
1543 "exe":"2.20.1.155.g426c96fcdb" # git version
1544}</code></pre>
1545</div></div>
1546</dd>
1547<dt class="hdlist1">
1548<code>"start"</code>
1549</dt>
1550<dd>
1551<p>
1552 This event contains the complete argv received by main().
1553</p>
1554<div class="listingblock">
1555<div class="content">
1556<pre><code>{
1557 "event":"start",
1558 ...
Junio C Hamano792b6092019-05-13 16:03:591559 "t_abs":0.001227, # elapsed time in seconds
Junio C Hamano11f15372019-03-07 03:17:001560 "argv":["git","version"]
1561}</code></pre>
1562</div></div>
1563</dd>
1564<dt class="hdlist1">
1565<code>"exit"</code>
1566</dt>
1567<dd>
1568<p>
1569 This event is emitted when git calls <code>exit()</code>.
1570</p>
1571<div class="listingblock">
1572<div class="content">
1573<pre><code>{
1574 "event":"exit",
1575 ...
1576 "t_abs":0.001227, # elapsed time in seconds
1577 "code":0 # exit code
1578}</code></pre>
1579</div></div>
1580</dd>
1581<dt class="hdlist1">
1582<code>"atexit"</code>
1583</dt>
1584<dd>
1585<p>
1586 This event is emitted by the Trace2 <code>atexit</code> routine during
1587 final shutdown. It should be the last event emitted by the
1588 process.
1589</p>
1590<div class="paragraph"><p>(The elapsed time reported here is greater than the time reported in
1591the "exit" event because it runs after all other atexit tasks have
1592completed.)</p></div>
1593<div class="listingblock">
1594<div class="content">
1595<pre><code>{
1596 "event":"atexit",
1597 ...
1598 "t_abs":0.001227, # elapsed time in seconds
1599 "code":0 # exit code
1600}</code></pre>
1601</div></div>
1602</dd>
1603<dt class="hdlist1">
1604<code>"signal"</code>
1605</dt>
1606<dd>
1607<p>
1608 This event is emitted when the program is terminated by a user
1609 signal. Depending on the platform, the signal event may
1610 prevent the "atexit" event from being generated.
1611</p>
1612<div class="listingblock">
1613<div class="content">
1614<pre><code>{
1615 "event":"signal",
1616 ...
1617 "t_abs":0.001227, # elapsed time in seconds
1618 "signal":13 # SIGTERM, SIGINT, etc.
1619}</code></pre>
1620</div></div>
1621</dd>
1622<dt class="hdlist1">
1623<code>"error"</code>
1624</dt>
1625<dd>
1626<p>
1627 This event is emitted when one of the <code>error()</code>, <code>die()</code>,
1628 or <code>usage()</code> functions are called.
1629</p>
1630<div class="listingblock">
1631<div class="content">
1632<pre><code>{
1633 "event":"error",
1634 ...
1635 "msg":"invalid option: --cahced", # formatted error message
1636 "fmt":"invalid option: %s" # error format string
1637}</code></pre>
1638</div></div>
1639<div class="paragraph"><p>The error event may be emitted more than once. The format string
1640allows post-processors to group errors by type without worrying
1641about specific error arguments.</p></div>
1642</dd>
1643<dt class="hdlist1">
1644<code>"cmd_path"</code>
1645</dt>
1646<dd>
1647<p>
1648 This event contains the discovered full path of the git
1649 executable (on platforms that are configured to resolve it).
1650</p>
1651<div class="listingblock">
1652<div class="content">
1653<pre><code>{
1654 "event":"cmd_path",
1655 ...
1656 "path":"C:/work/gfw/git.exe"
1657}</code></pre>
1658</div></div>
1659</dd>
1660<dt class="hdlist1">
1661<code>"cmd_name"</code>
1662</dt>
1663<dd>
1664<p>
1665 This event contains the command name for this git process
1666 and the hierarchy of commands from parent git processes.
1667</p>
1668<div class="listingblock">
1669<div class="content">
1670<pre><code>{
1671 "event":"cmd_name",
1672 ...
1673 "name":"pack-objects",
1674 "hierarchy":"push/pack-objects"
1675}</code></pre>
1676</div></div>
1677<div class="paragraph"><p>Normally, the "name" field contains the canonical name of the
1678command. When a canonical name is not available, one of
1679these special values are used:</p></div>
1680<div class="listingblock">
1681<div class="content">
1682<pre><code>"_query_" # "git --html-path"
1683"_run_dashed_" # when "git foo" tries to run "git-foo"
1684"_run_shell_alias_" # alias expansion to a shell command
1685"_run_git_alias_" # alias expansion to a git command
1686"_usage_" # usage error</code></pre>
1687</div></div>
1688</dd>
1689<dt class="hdlist1">
1690<code>"cmd_mode"</code>
1691</dt>
1692<dd>
1693<p>
1694 This event, when present, describes the command variant This
1695 event may be emitted more than once.
1696</p>
1697<div class="listingblock">
1698<div class="content">
1699<pre><code>{
1700 "event":"cmd_mode",
1701 ...
1702 "name":"branch"
1703}</code></pre>
1704</div></div>
1705<div class="paragraph"><p>The "name" field is an arbitrary string to describe the command mode.
1706For example, checkout can checkout a branch or an individual file.
1707And these variations typically have different performance
1708characteristics that are not comparable.</p></div>
1709</dd>
1710<dt class="hdlist1">
1711<code>"alias"</code>
1712</dt>
1713<dd>
1714<p>
1715 This event is present when an alias is expanded.
1716</p>
1717<div class="listingblock">
1718<div class="content">
1719<pre><code>{
1720 "event":"alias",
1721 ...
1722 "alias":"l", # registered alias
1723 "argv":["log","--graph"] # alias expansion
1724}</code></pre>
1725</div></div>
1726</dd>
1727<dt class="hdlist1">
1728<code>"child_start"</code>
1729</dt>
1730<dd>
1731<p>
1732 This event describes a child process that is about to be
1733 spawned.
1734</p>
1735<div class="listingblock">
1736<div class="content">
1737<pre><code>{
1738 "event":"child_start",
1739 ...
1740 "child_id":2,
1741 "child_class":"?",
1742 "use_shell":false,
1743 "argv":["git","rev-list","--objects","--stdin","--not","--all","--quiet"]
1744
1745 "hook_name":"&lt;hook_name&gt;" # present when child_class is "hook"
1746 "cd":"&lt;path&gt;" # present when cd is required
1747}</code></pre>
1748</div></div>
1749<div class="paragraph"><p>The "child_id" field can be used to match this child_start with the
1750corresponding child_exit event.</p></div>
1751<div class="paragraph"><p>The "child_class" field is a rough classification, such as "editor",
1752"pager", "transport/*", and "hook". Unclassified children are classified
1753with "?".</p></div>
1754</dd>
1755<dt class="hdlist1">
1756<code>"child_exit"</code>
1757</dt>
1758<dd>
1759<p>
1760 This event is generated after the current process has returned
1761 from the waitpid() and collected the exit information from the
1762 child.
1763</p>
1764<div class="listingblock">
1765<div class="content">
1766<pre><code>{
1767 "event":"child_exit",
1768 ...
1769 "child_id":2,
1770 "pid":14708, # child PID
1771 "code":0, # child exit-code
1772 "t_rel":0.110605 # observed run-time of child process
1773}</code></pre>
1774</div></div>
1775<div class="paragraph"><p>Note that the session-id of the child process is not available to
1776the current/spawning process, so the child&#8217;s PID is reported here as
1777a hint for post-processing. (But it is only a hint because the child
1778proces may be a shell script which doesn&#8217;t have a session-id.)</p></div>
1779<div class="paragraph"><p>Note that the <code>t_rel</code> field contains the observed run time in seconds
1780for the child process (starting before the fork/exec/spawn and
1781stopping after the waitpid() and includes OS process creation overhead).
1782So this time will be slightly larger than the atexit time reported by
1783the child process itself.</p></div>
1784</dd>
1785<dt class="hdlist1">
1786<code>"exec"</code>
1787</dt>
1788<dd>
1789<p>
1790 This event is generated before git attempts to <code>exec()</code>
1791 another command rather than starting a child process.
1792</p>
1793<div class="listingblock">
1794<div class="content">
1795<pre><code>{
1796 "event":"exec",
1797 ...
1798 "exec_id":0,
1799 "exe":"git",
1800 "argv":["foo", "bar"]
1801}</code></pre>
1802</div></div>
1803<div class="paragraph"><p>The "exec_id" field is a command-unique id and is only useful if the
1804<code>exec()</code> fails and a corresponding exec_result event is generated.</p></div>
1805</dd>
1806<dt class="hdlist1">
1807<code>"exec_result"</code>
1808</dt>
1809<dd>
1810<p>
1811 This event is generated if the <code>exec()</code> fails and control
1812 returns to the current git command.
1813</p>
1814<div class="listingblock">
1815<div class="content">
1816<pre><code>{
1817 "event":"exec_result",
1818 ...
1819 "exec_id":0,
1820 "code":1 # error code (errno) from exec()
1821}</code></pre>
1822</div></div>
1823</dd>
1824<dt class="hdlist1">
1825<code>"thread_start"</code>
1826</dt>
1827<dd>
1828<p>
1829 This event is generated when a thread is started. It is
1830 generated from <strong>within</strong> the new thread&#8217;s thread-proc (for TLS
1831 reasons).
1832</p>
1833<div class="listingblock">
1834<div class="content">
1835<pre><code>{
1836 "event":"thread_start",
1837 ...
1838 "thread":"th02:preload_thread" # thread name
1839}</code></pre>
1840</div></div>
1841</dd>
1842<dt class="hdlist1">
1843<code>"thread_exit"</code>
1844</dt>
1845<dd>
1846<p>
1847 This event is generated when a thread exits. It is generated
1848 from <strong>within</strong> the thread&#8217;s thread-proc (for TLS reasons).
1849</p>
1850<div class="listingblock">
1851<div class="content">
1852<pre><code>{
1853 "event":"thread_exit",
1854 ...
1855 "thread":"th02:preload_thread", # thread name
1856 "t_rel":0.007328 # thread elapsed time
1857}</code></pre>
1858</div></div>
1859</dd>
1860<dt class="hdlist1">
1861<code>"def_param"</code>
1862</dt>
1863<dd>
1864<p>
1865 This event is generated to log a global parameter.
1866</p>
1867<div class="listingblock">
1868<div class="content">
1869<pre><code>{
1870 "event":"def_param",
1871 ...
1872 "param":"core.abbrev",
1873 "value":"7"
1874}</code></pre>
1875</div></div>
1876</dd>
1877<dt class="hdlist1">
1878<code>"def_repo"</code>
1879</dt>
1880<dd>
1881<p>
1882 This event defines a repo-id and associates it with the root
1883 of the worktree.
1884</p>
1885<div class="listingblock">
1886<div class="content">
1887<pre><code>{
1888 "event":"def_repo",
1889 ...
1890 "repo":1,
1891 "worktree":"/Users/jeffhost/work/gfw"
1892}</code></pre>
1893</div></div>
1894<div class="paragraph"><p>As stated earlier, the repo-id is currently always 1, so there will
1895only be one def_repo event. Later, if in-proc submodules are
1896supported, a def_repo event should be emitted for each submodule
1897visited.</p></div>
1898</dd>
1899<dt class="hdlist1">
1900<code>"region_enter"</code>
1901</dt>
1902<dd>
1903<p>
1904 This event is generated when entering a region.
1905</p>
1906<div class="listingblock">
1907<div class="content">
1908<pre><code>{
1909 "event":"region_enter",
1910 ...
1911 "repo":1, # optional
1912 "nesting":1, # current region stack depth
1913 "category":"index", # optional
1914 "label":"do_read_index", # optional
1915 "msg":".git/index" # optional
1916}</code></pre>
1917</div></div>
1918<div class="paragraph"><p>The <code>category</code> field may be used in a future enhancement to
1919do category-based filtering.</p></div>
Junio C Hamanoc01eecf2019-05-30 18:17:471920<div class="paragraph"><p><code>GIT_TRACE2_EVENT_NESTING</code> or <code>trace2.eventNesting</code> can be used to
Junio C Hamano11f15372019-03-07 03:17:001921filter deeply nested regions and data events. It defaults to "2".</p></div>
1922</dd>
1923<dt class="hdlist1">
1924<code>"region_leave"</code>
1925</dt>
1926<dd>
1927<p>
1928 This event is generated when leaving a region.
1929</p>
1930<div class="listingblock">
1931<div class="content">
1932<pre><code>{
1933 "event":"region_leave",
1934 ...
1935 "repo":1, # optional
1936 "t_rel":0.002876, # time spent in region in seconds
1937 "nesting":1, # region stack depth
1938 "category":"index", # optional
1939 "label":"do_read_index", # optional
1940 "msg":".git/index" # optional
1941}</code></pre>
1942</div></div>
1943</dd>
1944<dt class="hdlist1">
1945<code>"data"</code>
1946</dt>
1947<dd>
1948<p>
1949 This event is generated to log a thread- and region-local
1950 key/value pair.
1951</p>
1952<div class="listingblock">
1953<div class="content">
1954<pre><code>{
1955 "event":"data",
1956 ...
1957 "repo":1, # optional
1958 "t_abs":0.024107, # absolute elapsed time
1959 "t_rel":0.001031, # elapsed time in region/thread
1960 "nesting":2, # region stack depth
1961 "category":"index",
1962 "key":"read/cache_nr",
1963 "value":"3552"
1964}</code></pre>
1965</div></div>
1966<div class="paragraph"><p>The "value" field may be an integer or a string.</p></div>
1967</dd>
1968<dt class="hdlist1">
1969<code>"data-json"</code>
1970</dt>
1971<dd>
1972<p>
1973 This event is generated to log a pre-formatted JSON string
1974 containing structured data.
1975</p>
1976<div class="listingblock">
1977<div class="content">
1978<pre><code>{
1979 "event":"data_json",
1980 ...
1981 "repo":1, # optional
1982 "t_abs":0.015905,
1983 "t_rel":0.015905,
1984 "nesting":1,
1985 "category":"process",
1986 "key":"windows/ancestry",
1987 "value":["bash.exe","bash.exe"]
1988}</code></pre>
1989</div></div>
1990</dd>
1991</dl></div>
1992</div>
1993</div>
1994</div>
1995</div>
1996<div class="sect1">
1997<h2 id="_example_trace2_api_usage">Example Trace2 API Usage</h2>
1998<div class="sectionbody">
1999<div class="paragraph"><p>Here is a hypothetical usage of the Trace2 API showing the intended
2000usage (without worrying about the actual Git details).</p></div>
2001<div class="dlist"><dl>
2002<dt class="hdlist1">
2003Initialization
2004</dt>
2005<dd>
2006<p>
2007 Initialization happens in <code>main()</code>. Behind the scenes, an
2008 <code>atexit</code> and <code>signal</code> handler are registered.
2009</p>
2010<div class="listingblock">
2011<div class="content">
2012<pre><code>int main(int argc, const char **argv)
2013{
2014 int exit_code;
2015
2016 trace2_initialize();
2017 trace2_cmd_start(argv);
2018
2019 exit_code = cmd_main(argc, argv);
2020
2021 trace2_cmd_exit(exit_code);
2022
2023 return exit_code;
2024}</code></pre>
2025</div></div>
2026</dd>
2027<dt class="hdlist1">
2028Command Details
2029</dt>
2030<dd>
2031<p>
2032 After the basics are established, additional command
2033 information can be sent to Trace2 as it is discovered.
2034</p>
2035<div class="listingblock">
2036<div class="content">
2037<pre><code>int cmd_checkout(int argc, const char **argv)
2038{
2039 trace2_cmd_name("checkout");
2040 trace2_cmd_mode("branch");
2041 trace2_def_repo(the_repository);
2042
2043 // emit "def_param" messages for "interesting" config settings.
2044 trace2_cmd_list_config();
2045
2046 if (do_something())
2047 trace2_cmd_error("Path '%s': cannot do something", path);
2048
2049 return 0;
2050}</code></pre>
2051</div></div>
2052</dd>
2053<dt class="hdlist1">
2054Child Processes
2055</dt>
2056<dd>
2057<p>
2058 Wrap code spawning child processes.
2059</p>
2060<div class="listingblock">
2061<div class="content">
2062<pre><code>void run_child(...)
2063{
2064 int child_exit_code;
2065 struct child_process cmd = CHILD_PROCESS_INIT;
2066 ...
2067 cmd.trace2_child_class = "editor";
2068
2069 trace2_child_start(&amp;cmd);
2070 child_exit_code = spawn_child_and_wait_for_it();
2071 trace2_child_exit(&amp;cmd, child_exit_code);
2072}</code></pre>
2073</div></div>
2074<div class="paragraph"><p>For example, the following fetch command spawned ssh, index-pack,
2075rev-list, and gc. This example also shows that fetch took
20765.199 seconds and of that 4.932 was in ssh.</p></div>
2077<div class="listingblock">
2078<div class="content">
Junio C Hamanoc01eecf2019-05-30 18:17:472079<pre><code>$ export GIT_TRACE2_BRIEF=1
2080$ export GIT_TRACE2=~/log.normal
Junio C Hamano11f15372019-03-07 03:17:002081$ git fetch origin
2082...</code></pre>
2083</div></div>
2084<div class="listingblock">
2085<div class="content">
2086<pre><code>$ cat ~/log.normal
2087version 2.20.1.vfs.1.1.47.g534dbe1ad1
2088start git fetch origin
2089worktree /Users/jeffhost/work/gfw
2090cmd_name fetch (fetch)
2091child_start[0] ssh git@github.com ...
2092child_start[1] git index-pack ...
2093... (Trace2 events from child processes omitted)
2094child_exit[1] pid:14707 code:0 elapsed:0.076353
2095child_exit[0] pid:14706 code:0 elapsed:4.931869
2096child_start[2] git rev-list ...
2097... (Trace2 events from child process omitted)
2098child_exit[2] pid:14708 code:0 elapsed:0.110605
2099child_start[3] git gc --auto
2100... (Trace2 events from child process omitted)
2101child_exit[3] pid:14709 code:0 elapsed:0.006240
2102exit elapsed:5.198503 code:0
2103atexit elapsed:5.198541 code:0</code></pre>
2104</div></div>
2105<div class="paragraph"><p>When a git process is a (direct or indirect) child of another
2106git process, it inherits Trace2 context information. This
2107allows the child to print the command hierarchy. This example
2108shows gc as child[3] of fetch. When the gc process reports
2109its name as "gc", it also reports the hierarchy as "fetch/gc".
2110(In this example, trace2 messages from the child process is
2111indented for clarity.)</p></div>
2112<div class="listingblock">
2113<div class="content">
Junio C Hamanoc01eecf2019-05-30 18:17:472114<pre><code>$ export GIT_TRACE2_BRIEF=1
2115$ export GIT_TRACE2=~/log.normal
Junio C Hamano11f15372019-03-07 03:17:002116$ git fetch origin
2117...</code></pre>
2118</div></div>
2119<div class="listingblock">
2120<div class="content">
2121<pre><code>$ cat ~/log.normal
2122version 2.20.1.160.g5676107ecd.dirty
2123start git fetch official
2124worktree /Users/jeffhost/work/gfw
2125cmd_name fetch (fetch)
2126...
2127child_start[3] git gc --auto
2128 version 2.20.1.160.g5676107ecd.dirty
2129 start /Users/jeffhost/work/gfw/git gc --auto
2130 worktree /Users/jeffhost/work/gfw
2131 cmd_name gc (fetch/gc)
2132 exit elapsed:0.001959 code:0
2133 atexit elapsed:0.001997 code:0
2134child_exit[3] pid:20303 code:0 elapsed:0.007564
2135exit elapsed:3.868938 code:0
2136atexit elapsed:3.868970 code:0</code></pre>
2137</div></div>
2138</dd>
2139<dt class="hdlist1">
2140Regions
2141</dt>
2142<dd>
2143<p>
2144 Regions can be use to time an interesting section of code.
2145</p>
2146<div class="listingblock">
2147<div class="content">
2148<pre><code>void wt_status_collect(struct wt_status *s)
2149{
2150 trace2_region_enter("status", "worktrees", s-&gt;repo);
2151 wt_status_collect_changes_worktree(s);
2152 trace2_region_leave("status", "worktrees", s-&gt;repo);
2153
2154 trace2_region_enter("status", "index", s-&gt;repo);
2155 wt_status_collect_changes_index(s);
2156 trace2_region_leave("status", "index", s-&gt;repo);
2157
2158 trace2_region_enter("status", "untracked", s-&gt;repo);
2159 wt_status_collect_untracked(s);
2160 trace2_region_leave("status", "untracked", s-&gt;repo);
2161}
2162
2163void wt_status_print(struct wt_status *s)
2164{
2165 trace2_region_enter("status", "print", s-&gt;repo);
2166 switch (s-&gt;status_format) {
2167 ...
2168 }
2169 trace2_region_leave("status", "print", s-&gt;repo);
2170}</code></pre>
2171</div></div>
2172<div class="paragraph"><p>In this example, scanning for untracked files ran from +0.012568 to
2173+0.027149 (since the process started) and took 0.014581 seconds.</p></div>
2174<div class="listingblock">
2175<div class="content">
Junio C Hamanoc01eecf2019-05-30 18:17:472176<pre><code>$ export GIT_TRACE2_PERF_BRIEF=1
2177$ export GIT_TRACE2_PERF=~/log.perf
Junio C Hamano11f15372019-03-07 03:17:002178$ git status
2179...
2180
2181$ cat ~/log.perf
2182d0 | main | version | | | | | 2.20.1.160.g5676107ecd.dirty
Junio C Hamano792b6092019-05-13 16:03:592183d0 | main | start | | 0.001173 | | | git status
Junio C Hamano11f15372019-03-07 03:17:002184d0 | main | def_repo | r1 | | | | worktree:/Users/jeffhost/work/gfw
2185d0 | main | cmd_name | | | | | status (status)
2186...
2187d0 | main | region_enter | r1 | 0.010988 | | status | label:worktrees
2188d0 | main | region_leave | r1 | 0.011236 | 0.000248 | status | label:worktrees
2189d0 | main | region_enter | r1 | 0.011260 | | status | label:index
2190d0 | main | region_leave | r1 | 0.012542 | 0.001282 | status | label:index
2191d0 | main | region_enter | r1 | 0.012568 | | status | label:untracked
2192d0 | main | region_leave | r1 | 0.027149 | 0.014581 | status | label:untracked
2193d0 | main | region_enter | r1 | 0.027411 | | status | label:print
2194d0 | main | region_leave | r1 | 0.028741 | 0.001330 | status | label:print
2195d0 | main | exit | | 0.028778 | | | code:0
2196d0 | main | atexit | | 0.028809 | | | code:0</code></pre>
2197</div></div>
2198<div class="paragraph"><p>Regions may be nested. This causes messages to be indented in the
2199PERF target, for example.
2200Elapsed times are relative to the start of the correpsonding nesting
2201level as expected. For example, if we add region message to:</p></div>
2202<div class="listingblock">
2203<div class="content">
2204<pre><code>static enum path_treatment read_directory_recursive(struct dir_struct *dir,
2205 struct index_state *istate, const char *base, int baselen,
2206 struct untracked_cache_dir *untracked, int check_only,
2207 int stop_at_first_file, const struct pathspec *pathspec)
2208{
2209 enum path_treatment state, subdir_state, dir_state = path_none;
2210
2211 trace2_region_enter_printf("dir", "read_recursive", NULL, "%.*s", baselen, base);
2212 ...
2213 trace2_region_leave_printf("dir", "read_recursive", NULL, "%.*s", baselen, base);
2214 return dir_state;
2215}</code></pre>
2216</div></div>
2217<div class="paragraph"><p>We can further investigate the time spent scanning for untracked files.</p></div>
2218<div class="listingblock">
2219<div class="content">
Junio C Hamanoc01eecf2019-05-30 18:17:472220<pre><code>$ export GIT_TRACE2_PERF_BRIEF=1
2221$ export GIT_TRACE2_PERF=~/log.perf
Junio C Hamano11f15372019-03-07 03:17:002222$ git status
2223...
2224$ cat ~/log.perf
2225d0 | main | version | | | | | 2.20.1.162.gb4ccea44db.dirty
Junio C Hamano792b6092019-05-13 16:03:592226d0 | main | start | | 0.001173 | | | git status
Junio C Hamano11f15372019-03-07 03:17:002227d0 | main | def_repo | r1 | | | | worktree:/Users/jeffhost/work/gfw
2228d0 | main | cmd_name | | | | | status (status)
2229...
2230d0 | main | region_enter | r1 | 0.015047 | | status | label:untracked
2231d0 | main | region_enter | | 0.015132 | | dir | ..label:read_recursive
2232d0 | main | region_enter | | 0.016341 | | dir | ....label:read_recursive vcs-svn/
2233d0 | main | region_leave | | 0.016422 | 0.000081 | dir | ....label:read_recursive vcs-svn/
2234d0 | main | region_enter | | 0.016446 | | dir | ....label:read_recursive xdiff/
2235d0 | main | region_leave | | 0.016522 | 0.000076 | dir | ....label:read_recursive xdiff/
2236d0 | main | region_enter | | 0.016612 | | dir | ....label:read_recursive git-gui/
2237d0 | main | region_enter | | 0.016698 | | dir | ......label:read_recursive git-gui/po/
2238d0 | main | region_enter | | 0.016810 | | dir | ........label:read_recursive git-gui/po/glossary/
2239d0 | main | region_leave | | 0.016863 | 0.000053 | dir | ........label:read_recursive git-gui/po/glossary/
2240...
2241d0 | main | region_enter | | 0.031876 | | dir | ....label:read_recursive builtin/
2242d0 | main | region_leave | | 0.032270 | 0.000394 | dir | ....label:read_recursive builtin/
2243d0 | main | region_leave | | 0.032414 | 0.017282 | dir | ..label:read_recursive
2244d0 | main | region_leave | r1 | 0.032454 | 0.017407 | status | label:untracked
2245...
2246d0 | main | exit | | 0.034279 | | | code:0
2247d0 | main | atexit | | 0.034322 | | | code:0</code></pre>
2248</div></div>
2249<div class="paragraph"><p>Trace2 regions are similar to the existing trace_performance_enter()
2250and trace_performance_leave() routines, but are thread safe and
2251maintain per-thread stacks of timers.</p></div>
2252</dd>
2253<dt class="hdlist1">
2254Data Messages
2255</dt>
2256<dd>
2257<p>
2258 Data messages added to a region.
2259</p>
2260<div class="listingblock">
2261<div class="content">
2262<pre><code>int read_index_from(struct index_state *istate, const char *path,
2263 const char *gitdir)
2264{
2265 trace2_region_enter_printf("index", "do_read_index", the_repository, "%s", path);
2266
2267 ...
2268
2269 trace2_data_intmax("index", the_repository, "read/version", istate-&gt;version);
2270 trace2_data_intmax("index", the_repository, "read/cache_nr", istate-&gt;cache_nr);
2271
2272 trace2_region_leave_printf("index", "do_read_index", the_repository, "%s", path);
2273}</code></pre>
2274</div></div>
2275<div class="paragraph"><p>This example shows that the index contained 3552 entries.</p></div>
2276<div class="listingblock">
2277<div class="content">
Junio C Hamanoc01eecf2019-05-30 18:17:472278<pre><code>$ export GIT_TRACE2_PERF_BRIEF=1
2279$ export GIT_TRACE2_PERF=~/log.perf
Junio C Hamano11f15372019-03-07 03:17:002280$ git status
2281...
2282$ cat ~/log.perf
2283d0 | main | version | | | | | 2.20.1.156.gf9916ae094.dirty
Junio C Hamano792b6092019-05-13 16:03:592284d0 | main | start | | 0.001173 | | | git status
Junio C Hamano11f15372019-03-07 03:17:002285d0 | main | def_repo | r1 | | | | worktree:/Users/jeffhost/work/gfw
2286d0 | main | cmd_name | | | | | status (status)
2287d0 | main | region_enter | r1 | 0.001791 | | index | label:do_read_index .git/index
2288d0 | main | data | r1 | 0.002494 | 0.000703 | index | ..read/version:2
2289d0 | main | data | r1 | 0.002520 | 0.000729 | index | ..read/cache_nr:3552
2290d0 | main | region_leave | r1 | 0.002539 | 0.000748 | index | label:do_read_index .git/index
2291...</code></pre>
2292</div></div>
2293</dd>
2294<dt class="hdlist1">
2295Thread Events
2296</dt>
2297<dd>
2298<p>
2299 Thread messages added to a thread-proc.
2300</p>
2301<div class="paragraph"><p>For example, the multithreaded preload-index code can be
2302instrumented with a region around the thread pool and then
2303per-thread start and exit events within the threadproc.</p></div>
2304<div class="listingblock">
2305<div class="content">
2306<pre><code>static void *preload_thread(void *_data)
2307{
2308 // start the per-thread clock and emit a message.
2309 trace2_thread_start("preload_thread");
2310
2311 // report which chunk of the array this thread was assigned.
2312 trace2_data_intmax("index", the_repository, "offset", p-&gt;offset);
2313 trace2_data_intmax("index", the_repository, "count", nr);
2314
2315 do {
2316 ...
2317 } while (--nr &gt; 0);
2318 ...
2319
2320 // report elapsed time taken by this thread.
2321 trace2_thread_exit();
2322 return NULL;
2323}
2324
2325void preload_index(struct index_state *index,
2326 const struct pathspec *pathspec,
2327 unsigned int refresh_flags)
2328{
2329 trace2_region_enter("index", "preload", the_repository);
2330
2331 for (i = 0; i &lt; threads; i++) {
2332 ... /* create thread */
2333 }
2334
2335 for (i = 0; i &lt; threads; i++) {
2336 ... /* join thread */
2337 }
2338
2339 trace2_region_leave("index", "preload", the_repository);
2340}</code></pre>
2341</div></div>
2342<div class="paragraph"><p>In this example preload_index() was executed by the <code>main</code> thread
2343and started the <code>preload</code> region. Seven threads, named
2344<code>th01:preload_thread</code> through <code>th07:preload_thread</code>, were started.
2345Events from each thread are atomically appended to the shared target
2346stream as they occur so they may appear in random order with respect
2347other threads. Finally, the main thread waits for the threads to
2348finish and leaves the region.</p></div>
2349<div class="paragraph"><p>Data events are tagged with the active thread name. They are used
2350to report the per-thread parameters.</p></div>
2351<div class="listingblock">
2352<div class="content">
Junio C Hamanoc01eecf2019-05-30 18:17:472353<pre><code>$ export GIT_TRACE2_PERF_BRIEF=1
2354$ export GIT_TRACE2_PERF=~/log.perf
Junio C Hamano11f15372019-03-07 03:17:002355$ git status
2356...
2357$ cat ~/log.perf
2358...
2359d0 | main | region_enter | r1 | 0.002595 | | index | label:preload
2360d0 | th01:preload_thread | thread_start | | 0.002699 | | |
2361d0 | th02:preload_thread | thread_start | | 0.002721 | | |
2362d0 | th01:preload_thread | data | r1 | 0.002736 | 0.000037 | index | offset:0
2363d0 | th02:preload_thread | data | r1 | 0.002751 | 0.000030 | index | offset:2032
2364d0 | th03:preload_thread | thread_start | | 0.002711 | | |
2365d0 | th06:preload_thread | thread_start | | 0.002739 | | |
2366d0 | th01:preload_thread | data | r1 | 0.002766 | 0.000067 | index | count:508
2367d0 | th06:preload_thread | data | r1 | 0.002856 | 0.000117 | index | offset:2540
2368d0 | th03:preload_thread | data | r1 | 0.002824 | 0.000113 | index | offset:1016
2369d0 | th04:preload_thread | thread_start | | 0.002710 | | |
2370d0 | th02:preload_thread | data | r1 | 0.002779 | 0.000058 | index | count:508
2371d0 | th06:preload_thread | data | r1 | 0.002966 | 0.000227 | index | count:508
2372d0 | th07:preload_thread | thread_start | | 0.002741 | | |
2373d0 | th07:preload_thread | data | r1 | 0.003017 | 0.000276 | index | offset:3048
2374d0 | th05:preload_thread | thread_start | | 0.002712 | | |
2375d0 | th05:preload_thread | data | r1 | 0.003067 | 0.000355 | index | offset:1524
2376d0 | th05:preload_thread | data | r1 | 0.003090 | 0.000378 | index | count:508
2377d0 | th07:preload_thread | data | r1 | 0.003037 | 0.000296 | index | count:504
2378d0 | th03:preload_thread | data | r1 | 0.002971 | 0.000260 | index | count:508
2379d0 | th04:preload_thread | data | r1 | 0.002983 | 0.000273 | index | offset:508
2380d0 | th04:preload_thread | data | r1 | 0.007311 | 0.004601 | index | count:508
2381d0 | th05:preload_thread | thread_exit | | 0.008781 | 0.006069 | |
2382d0 | th01:preload_thread | thread_exit | | 0.009561 | 0.006862 | |
2383d0 | th03:preload_thread | thread_exit | | 0.009742 | 0.007031 | |
2384d0 | th06:preload_thread | thread_exit | | 0.009820 | 0.007081 | |
2385d0 | th02:preload_thread | thread_exit | | 0.010274 | 0.007553 | |
2386d0 | th07:preload_thread | thread_exit | | 0.010477 | 0.007736 | |
2387d0 | th04:preload_thread | thread_exit | | 0.011657 | 0.008947 | |
2388d0 | main | region_leave | r1 | 0.011717 | 0.009122 | index | label:preload
2389...
2390d0 | main | exit | | 0.029996 | | | code:0
2391d0 | main | atexit | | 0.030027 | | | code:0</code></pre>
2392</div></div>
2393<div class="paragraph"><p>In this example, the preload region took 0.009122 seconds. The 7 threads
2394took between 0.006069 and 0.008947 seconds to work on their portion of
2395the index. Thread "th01" worked on 508 items at offset 0. Thread "th02"
2396worked on 508 items at offset 2032. Thread "th04" worked on 508 itemts
2397at offset 508.</p></div>
2398<div class="paragraph"><p>This example also shows that thread names are assigned in a racy manner
2399as each thread starts and allocates TLS storage.</p></div>
2400</dd>
2401</dl></div>
2402</div>
2403</div>
2404<div class="sect1">
2405<h2 id="_future_work">Future Work</h2>
2406<div class="sectionbody">
2407<div class="sect2">
2408<h3 id="_relationship_to_the_existing_trace_api_api_trace_txt">Relationship to the Existing Trace Api (api-trace.txt)</h3>
2409<div class="paragraph"><p>There are a few issues to resolve before we can completely
2410switch to Trace2.</p></div>
2411<div class="ulist"><ul>
2412<li>
2413<p>
2414Updating existing tests that assume GIT_TRACE format messages.
2415</p>
2416</li>
2417<li>
2418<p>
2419How to best handle custom GIT_TRACE_&lt;key&gt; messages?
2420</p>
2421<div class="ulist"><ul>
2422<li>
2423<p>
2424The GIT_TRACE_&lt;key&gt; mechanism allows each &lt;key&gt; to write to a
2425different file (in addition to just stderr).
2426</p>
2427</li>
2428<li>
2429<p>
2430Do we want to maintain that ability or simply write to the existing
2431Trace2 targets (and convert &lt;key&gt; to a "category").
2432</p>
2433</li>
2434</ul></div>
2435</li>
2436</ul></div>
2437</div>
2438</div>
2439</div>
2440</div>
2441<div id="footnotes"><hr /></div>
2442<div id="footer">
2443<div id="footer-text">
2444Last updated
Junio C Hamanoc01eecf2019-05-30 18:17:472445 2019-05-30 11:14:50 PDT
Junio C Hamano11f15372019-03-07 03:17:002446</div>
2447</div>
2448</body>
2449</html>