<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc 3.10" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>p4survey</title>
<style>
/* Default styles provided by pandoc.
** See https://pandoc.org/MANUAL.html#variables-for-html for config info.
*/
html {
color: #1a1a1a;
background-color: #fdfdfd;
}
body {
margin: 0 auto;
max-width: 36em;
padding-left: 50px;
padding-right: 50px;
padding-top: 50px;
padding-bottom: 50px;
hyphens: auto;
overflow-wrap: break-word;
text-rendering: optimizeLegibility;
font-kerning: normal;
}
@media (max-width: 600px) {
body {
font-size: 0.9em;
padding: 12px;
}
h1 {
font-size: 1.8em;
}
}
@media print {
html {
background-color: white;
}
body {
background-color: transparent;
color: black;
font-size: 12pt;
}
p, h2, h3 {
orphans: 3;
widows: 3;
}
h2, h3, h4 {
page-break-after: avoid;
}
}
p {
margin: 1em 0;
}
a {
color: #1a1a1a;
}
a:visited {
color: #1a1a1a;
}
img {
max-width: 100%;
}
svg {
height: auto;
max-width: 100%;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 1.4em;
}
h5, h6 {
font-size: 1em;
font-style: italic;
}
h6 {
font-weight: normal;
}
ol, ul {
padding-left: 1.7em;
margin-top: 1em;
}
li > ol, li > ul {
margin-top: 0;
}
blockquote {
margin: 1em 0 1em 1.7em;
padding-left: 1em;
border-left: 2px solid #e6e6e6;
color: #606060;
}
code {
white-space: pre-wrap;
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
font-size: 85%;
margin: 0;
hyphens: manual;
}
pre {
margin: 1em 0;
overflow: auto;
}
pre code {
padding: 0;
overflow: visible;
overflow-wrap: normal;
}
.sourceCode {
background-color: transparent;
overflow: visible;
}
hr {
border: none;
border-top: 1px solid #1a1a1a;
height: 1px;
margin: 1em 0;
}
table {
margin: 1em 0;
border-collapse: collapse;
width: 100%;
overflow-x: auto;
display: block;
font-variant-numeric: lining-nums tabular-nums;
}
table caption {
margin-bottom: 0.75em;
}
tbody {
margin-top: 0.5em;
border-top: 1px solid #1a1a1a;
border-bottom: 1px solid #1a1a1a;
}
th {
border-top: 1px solid #1a1a1a;
padding: 0.25em 0.5em 0.25em 0.5em;
}
td {
padding: 0.125em 0.5em 0.25em 0.5em;
}
header {
margin-bottom: 4em;
text-align: center;
}
#TOC li {
list-style: none;
}
#TOC ul {
padding-left: 1.3em;
}
#TOC > ul {
padding-left: 0;
}
#TOC a:not(:hover) {
text-decoration: none;
}
span.smallcaps{font-variant: small-caps;}
div.columns{display: flex; gap: 1.5em;}
div.column{flex: auto;}
@media screen {
div.columns{gap: min(4vw, 1.5em);}
div.column{overflow-x: auto;}
}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
/* The extra [class] is a hack that increases specificity enough to
override a similar rule in reveal.js */
ul.task-list[class]{list-style: none;}
ul.task-list li input[type="checkbox"] {
font-size: inherit;
width: 0.8em;
margin: 0 0.8em 0.2em -1.6em;
vertical-align: middle;
}
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
/* CSS for syntax highlighting */
html { -webkit-text-size-adjust: 100%; }
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { color: #008000; } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { color: #008000; font-weight: bold; } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>
<style>
:root {
color: #1f2933;
background: #eef3f6;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
line-height: 1.6;
}
body {
box-sizing: border-box;
max-width: 58rem;
margin: 2.5rem auto;
padding: 3rem clamp(1.5rem, 5vw, 4.5rem);
background: #ffffff;
border-top: 5px solid #4b778d;
box-shadow: 0 0.75rem 2.5rem rgb(31 41 51 / 12%);
}
h1, h2, h3 {
color: #173f52;
line-height: 1.2;
}
h1 {
margin-top: 0;
padding-bottom: 0.7rem;
border-bottom: 1px solid #d6e1e6;
font-size: 2.4rem;
}
h2 {
margin-top: 2.4rem;
padding-bottom: 0.35rem;
border-bottom: 1px solid #d6e1e6;
font-size: 1.55rem;
}
h3 {
margin-top: 1.8rem;
font-size: 1.2rem;
}
a, a:visited {
color: #0d6b85;
}
a:hover {
color: #a74725;
}
#TOC {
margin: 2rem 0;
padding: 1.25rem 1.5rem;
background: #f3f7f8;
border-left: 4px solid #4b778d;
}
#TOC > ul { margin-bottom: 0; }
#TOC li { margin: 0.3rem 0; }
code {
padding: 0.1em 0.3em;
background: #edf2f4;
border-radius: 3px;
color: #173f52;
}
pre {
padding: 1rem 1.2rem;
background: #edf2f4;
border-left: 4px solid #4b778d;
border-radius: 4px;
box-shadow: inset 0 0 0 1px #d6e1e6;
}
pre code {
padding: 0;
background: transparent;
color: #1f2933;
}
pre code.sourceCode > span { color: #1f2933; }
pre code.sourceCode span.cf,
pre code.sourceCode span.im,
pre code.sourceCode span.kw,
pre code.sourceCode span.ot { color: #18753d; }
pre code.sourceCode span.ch,
pre code.sourceCode span.sc,
pre code.sourceCode span.st,
pre code.sourceCode span.vs { color: #a55310; }
pre code.sourceCode span.co,
pre code.sourceCode span.cv { color: #4d6572; }
pre code.sourceCode span.fu,
pre code.sourceCode span.va { color: #155f87; }
pre code.sourceCode span.op { color: #445761; }
img {
display: block;
margin: 1.5rem auto;
border: 1px solid #d6e1e6;
box-shadow: 0 0.4rem 1.2rem rgb(31 41 51 / 14%);
}
@media (max-width: 600px) {
body {
margin: 0;
padding: 1.5rem;
box-shadow: none;
}
h1 { font-size: 2rem; }
}
@media print {
:root { background: #ffffff; }
body {
max-width: none;
margin: 0;
padding: 0;
border: 0;
box-shadow: none;
}
}
</style>
</head>
<body>
<header id="title-block-header">
<h1 class="title">p4survey</h1>
</header>
<nav id="TOC" role="doc-toc">
<ul>
<li><a href="#p4survey" id="toc-p4survey">p4survey</a>
<ul>
<li><a href="#overview" id="toc-overview">Overview</a></li>
<li><a href="#downloads" id="toc-downloads">Downloads</a></li>
<li><a href="#help" id="toc-help">Help</a></li>
<li><a href="#p4-commands-run-by-p4survey"
id="toc-p4-commands-run-by-p4survey">P4 commands run by
p4survey</a></li>
<li><a href="#p4_topology_diagram.py"
id="toc-p4_topology_diagram.py">p4_topology_diagram.py</a>
<ul>
<li><a href="#download" id="toc-download">Download</a></li>
<li><a href="#installation" id="toc-installation">Installation</a></li>
<li><a href="#usage" id="toc-usage">Usage</a></li>
<li><a href="#example-output" id="toc-example-output">Example
output</a></li>
</ul></li>
</ul></li>
</ul>
</nav>
<h1 id="p4survey">p4survey</h1>
<p>A survey tool to gather basic information about a P4
installation.</p>
<p>Includes an optional python script to create topology diagrams of
your servers.</p>
<p><em>Table of Contents</em></p>
<ul>
<li><a href="#p4survey">p4survey</a>
<ul>
<li><a href="#overview">Overview</a></li>
<li><a href="#downloads">Downloads</a></li>
<li><a href="#help">Help</a></li>
<li><a href="#p4-commands-run-by-p4survey">P4 commands run by
p4survey</a></li>
<li><a href="#p4_topology_diagrampy">p4_topology_diagram.py</a>
<ul>
<li><a href="#download">Download</a></li>
<li><a href="#installation">Installation</a></li>
<li><a href="#usage">Usage</a></li>
<li><a href="#example-output">Example output</a></li>
</ul></li>
</ul></li>
</ul>
<h2 id="overview">Overview</h2>
<p>Download for your platform and execute.</p>
<p>The following should be defined in your environment (easiest) or can
be provided as parameters to the tool:</p>
<ul>
<li>P4PORT - the p4d server you are talking to</li>
<li>P4USER - the p4d user account you are using</li>
<li>P4BIN - the path to the <code>p4</code> or <code>p4.exe</code> if it
is not in your <code>$PATH</code> for your shell</li>
</ul>
<p>Please note you should have logged in to the p4d server already, and
have <code>super</code> privileges (to be able to execute some
commands)</p>
<p>Tool with exit with an error if not being run as a logged in super
user!</p>
<h2 id="downloads">Downloads</h2>
<ul>
<li><a
href="https://swarm.workshop.perforce.com/downloads/guest/perforce_software/p4survey/bin/p4survey.linux-amd64.gz">For
Linux AMD64</a> - or <a
href="https://swarm.workshop.perforce.com/files/guest/perforce_software/p4survey/bin/p4survey.linux-amd64.gz">click
for file history</a></li>
<li><a
href="https://swarm.workshop.perforce.com/downloads/guest/perforce_software/p4survey/bin/p4survey.linux-arm64.gz">For
Linux ARM64</a> - or<a
href="https://swarm.workshop.perforce.com/files/guest/perforce_software/p4survey/bin/p4survey.linux-arm64.gz">click
for file history</a></li>
<li><a
href="https://swarm.workshop.perforce.com/downloads/guest/perforce_software/p4survey/bin/p4survey.darwin-arm64.gz">For
Mac/DARWIN ARM64</a> - or <a
href="https://swarm.workshop.perforce.com/files/guest/perforce_software/p4survey/bin/p4survey.darwin-arm64.gz">click
for file history</a></li>
<li><a
href="https://swarm.workshop.perforce.com/downloads/guest/perforce_software/p4survey/bin/p4survey.darwin-amd64.gz">For
Mac/DARWIN AMD64</a> - or <a
href="https://swarm.workshop.perforce.com/files/guest/perforce_software/p4survey/bin/p4survey.darwin-amd64.gz">click
for file history</a></li>
<li><a
href="https://swarm.workshop.perforce.com/downloads/guest/perforce_software/p4survey/bin/p4survey.windows-amd64.exe">For
Windows AMD64</a> - or<a
href="https://swarm.workshop.perforce.com/files/guest/perforce_software/p4survey/bin/p4survey.windows-amd64.exe">click
for file history</a></li>
</ul>
<p>After downloading, unzip (gunzip) and if necessary make
executable.</p>
<p>E.g. for Linux:</p>
<pre class="[bash]"><code>wget https://swarm.workshop.perforce.com/downloads/guest/perforce_software/p4survey/bin/p4survey.linux-amd64.gz
gunzip p4survey.linux-amd64.gz
chmod +x p4survey.linux-amd64
./p4survey.linux-amd64 -h</code></pre>
<p>To run:</p>
<pre class="[bash]"><code>./p4survey.linux-amd64
Running p4survey analysis as user "jbloggs" on P4PORT "some-server:2001"
Markdown report written: p4survey.XXXX.md
If you have any questions, please contact [email protected]</code></pre>
<p>Send the resulting file: p4survey.XXXX.md</p>
<h2 id="help">Help</h2>
<pre class="[bash]"><code>usage: p4survey [<flags>]
A survey tool for Perforce P4 servers. Will report on the server configuration.
Must be run as a logged in superuser.
Flags:
-h, --help Show context-sensitive help (also try --help-long and --help-man).
--p4user=P4USER (Optional) Perforce user (default $P4USER)
--p4port=P4PORT (Optional) Perforce server port (default $P4PORT)
--p4bin=P4BIN (Optional) Full path of p4 CLI (default is 'p4' in $PATH)
--topology Collect topology data for p4_topology_diagram.py
--topology-svg Collect topology data and render a pure-Go SVG diagram
--topology-layout=layered
SVG layout: layered or sfdp
--topology-input=TOPOLOGY-INPUT
Render a pure-Go SVG diagram from saved topology JSON
--debug Debug output
-V, --version Show application version.</code></pre>
<p>The output will be a Markdown formatted file which can be zipped and
sent to consulting or support.</p>
<p><code>--topology-svg</code> also writes
<code>p4_topology.<host>.<timestamp>.svg</code>. Its
deterministic, pure-Go layered layout groups replication trees, orders
nodes to reduce crossed links, and adapts spacing to the diagram’s
labels. It does not require CGO or an external Graphviz installation.
Open the SVG in a browser to drag nodes, Shift-click nodes to select and
move a group, and use the embedded <strong>Save layout</strong> control
to download the edited diagram.</p>
<p>Use <code>--topology-layout=sfdp</code> to use Graphviz
<code>sfdp</code> when it is installed and available on
<code>PATH</code>. It uses the same overlap settings as the Python
renderer. The default <code>layered</code> mode remains the
project-local deterministic layout and does not require Graphviz.</p>
<p>To render a previously saved topology file without connecting to P4
or running a survey, use:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./p4survey</span> <span class="at">--topology-input</span> p4_topology_data.example.json</span></code></pre></div>
<p>This writes <code>p4_topology_data.example.svg</code> beside the
input file.</p>
<h2 id="p4-commands-run-by-p4survey">P4 commands run by p4survey</h2>
<p>The following commands are run:</p>
<pre class="[bash]"><code>p4 -ztag info
p4 license -u
p4 diskspace
p4 configure show allservers
p4 servers -J
p4 -ztag servers
p4 -ztag depots
p4 triggers -o
p4 extension --list --type extensions
p4 extension --list --type global
p4 extension --list --type instance
p4 extension --list --type certs
p4 property -n P4.Swarm.URL -l
p4 keys -e "swarm-*" -m 1
p4 keys -e "git-*" -m 1
p4 typemap -o
p4 jobspec -o
p4 counter change
p4 dbstat -s
p4 journals -m 3
p4 protects -u remote</code></pre>
<h2 id="p4_topology_diagram.py">p4_topology_diagram.py</h2>
<p>This script will create a topology diagram in different output
formats (svg, html with D3, mermaid for markdown or asciidoc).</p>
<p>It runs the following 2 commands against your server and matches up
the output.</p>
<ul>
<li><code>p4 servers</code></li>
<li><code>p4 topology -t 2</code> (last 2 days worth of data)</li>
</ul>
<h3 id="download">Download</h3>
<p>See:</p>
<ul>
<li><a
href="https://swarm.workshop.perforce.com/downloads/guest/perforce_software/p4survey/p4_topology_diagram.py">p4_topology_diagram.py</a></li>
</ul>
<h3 id="installation">Installation</h3>
<p>Requires <code>python3</code> and <code>p4python</code>:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="ot">! </span><span class="bu">command</span> <span class="at">-v</span> uv <span class="op">></span>/dev/null <span class="dv">2</span><span class="op">>&</span><span class="dv">1</span><span class="kw">;</span> <span class="cf">then</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a> <span class="ex">curl</span> <span class="at">-LsSf</span> <span class="st">"https://astral.sh/uv/install.sh"</span> <span class="kw">|</span> <span class="fu">sh</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a> <span class="bu">export</span> <span class="va">PATH</span><span class="op">=</span><span class="st">"</span><span class="va">$HOME</span><span class="st">/.local/bin:</span><span class="va">$PATH</span><span class="st">"</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="cf">fi</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="ex">uv</span> python install</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a><span class="ex">uv</span> venv .venv</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="bu">source</span> .venv/bin/activate</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="ex">uv</span> pip install p4python</span></code></pre></div>
<p>You need to run it as a p4 user with <code>super</code>
permissions.</p>
<h3 id="usage">Usage</h3>
<p>Note that it is likely a good idea to try installing Graphviz locally
which allows you to use different <code>--layout</code> options
below.</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./p4_topology_diagram.py</span> <span class="at">-h</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="ex">usage:</span> p4_topology_diagram.py <span class="pp">[-</span><span class="ss">h</span><span class="pp">]</span> [--input-json INPUT_JSON] [--json-output JSON_OUTPUT] [--mermaid-output MERMAID_OUTPUT]</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a> <span class="ex">[--markdown-output</span> MARKDOWN_OUTPUT] [--asciidoc-output ASCIIDOC_OUTPUT] [--html-output HTML_OUTPUT]</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a> <span class="ex">[--svg-output</span> SVG_OUTPUT] [--layout <span class="dt">{auto</span><span class="op">,</span><span class="dt">sugiyama</span><span class="op">,</span><span class="dt">dot</span><span class="op">,</span><span class="dt">neato</span><span class="op">,</span><span class="dt">fdp</span><span class="op">,</span><span class="dt">sfdp</span><span class="op">,</span><span class="dt">circo</span><span class="op">,</span><span class="dt">twopi</span><span class="op">,</span><span class="dt">osage</span><span class="op">,</span><span class="dt">grid}</span>] [--title TITLE]</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a> <span class="ex">[--p4port</span> P4PORT] [--p4user P4USER]</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a><span class="ex">Collect</span> Perforce topology data and render a Mermaid diagram or other output formats.</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a><span class="ex">The</span> script can either:</span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a><span class="ex">1.</span> run the live commands needed to collect topology data <span class="er">(</span><span class="ex">p4</span> servers/p4 topology<span class="kw">)</span><span class="ex">,</span> or</span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a><span class="ex">2.</span> render from a previously collected JSON file.</span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a><span class="ex">Outputs:</span></span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a><span class="ex">-</span> JSON intermediate file with raw command output and normalized records</span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a><span class="ex">-</span> Mermaid diagram source</span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a><span class="ex">-</span> Markdown file wrapping the Mermaid diagram in a fenced block</span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true" tabindex="-1"></a><span class="ex">-</span> AsciiDoc block wrapping the Mermaid diagram for direct inclusion</span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true" tabindex="-1"></a><span class="ex">-</span> SVG diagram with drag-and-save support</span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true" tabindex="-1"></a><span class="ex">-</span> HTML page with interactive D3.js diagram</span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true" tabindex="-1"></a><span class="ex">If</span> you have Graphviz installed, you can use the <span class="at">--layout</span> option to generate a more compact SVG layout.</span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true" tabindex="-1"></a><span class="ex">If</span> you have the fast-sugiyama python pip package installed, it will be used first</span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> a <span class="ex">better</span> layout unless <span class="at">--layout</span> is set to one of its various options.</span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true" tabindex="-1"></a><span class="ex">If</span> neither fast-sugiyama nor Graphviz are available, a simple grid layout will be used.</span>
<span id="cb7-25"><a href="#cb7-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-26"><a href="#cb7-26" aria-hidden="true" tabindex="-1"></a><span class="ex">options:</span></span>
<span id="cb7-27"><a href="#cb7-27" aria-hidden="true" tabindex="-1"></a> <span class="ex">-h,</span> <span class="at">--help</span> show this help message and exit</span>
<span id="cb7-28"><a href="#cb7-28" aria-hidden="true" tabindex="-1"></a> <span class="ex">--input-json</span> INPUT_JSON</span>
<span id="cb7-29"><a href="#cb7-29" aria-hidden="true" tabindex="-1"></a> <span class="ex">Use</span> an existing JSON intermediate file instead of running live commands.</span>
<span id="cb7-30"><a href="#cb7-30" aria-hidden="true" tabindex="-1"></a> <span class="ex">--json-output</span> JSON_OUTPUT</span>
<span id="cb7-31"><a href="#cb7-31" aria-hidden="true" tabindex="-1"></a> <span class="ex">Path</span> to write the JSON intermediate file.</span>
<span id="cb7-32"><a href="#cb7-32" aria-hidden="true" tabindex="-1"></a> <span class="ex">--mermaid-output</span> MERMAID_OUTPUT</span>
<span id="cb7-33"><a href="#cb7-33" aria-hidden="true" tabindex="-1"></a> <span class="ex">Path</span> to write the Mermaid diagram source.</span>
<span id="cb7-34"><a href="#cb7-34" aria-hidden="true" tabindex="-1"></a> <span class="ex">--markdown-output</span> MARKDOWN_OUTPUT</span>
<span id="cb7-35"><a href="#cb7-35" aria-hidden="true" tabindex="-1"></a> <span class="ex">Path</span> to write the Markdown file containing the Mermaid diagram.</span>
<span id="cb7-36"><a href="#cb7-36" aria-hidden="true" tabindex="-1"></a> <span class="ex">--asciidoc-output</span> ASCIIDOC_OUTPUT</span>
<span id="cb7-37"><a href="#cb7-37" aria-hidden="true" tabindex="-1"></a> <span class="ex">Path</span> to write an AsciiDoc Mermaid block.</span>
<span id="cb7-38"><a href="#cb7-38" aria-hidden="true" tabindex="-1"></a> <span class="ex">--html-output</span> HTML_OUTPUT</span>
<span id="cb7-39"><a href="#cb7-39" aria-hidden="true" tabindex="-1"></a> <span class="ex">Path</span> to write the interactive D3.js HTML diagram.</span>
<span id="cb7-40"><a href="#cb7-40" aria-hidden="true" tabindex="-1"></a> <span class="ex">--svg-output</span> SVG_OUTPUT</span>
<span id="cb7-41"><a href="#cb7-41" aria-hidden="true" tabindex="-1"></a> <span class="ex">Path</span> to write a laid-out SVG diagram with drag-and-save support.</span>
<span id="cb7-42"><a href="#cb7-42" aria-hidden="true" tabindex="-1"></a> <span class="ex">--layout</span> <span class="dt">{auto</span><span class="op">,</span><span class="dt">sugiyama</span><span class="op">,</span><span class="dt">dot</span><span class="op">,</span><span class="dt">neato</span><span class="op">,</span><span class="dt">fdp</span><span class="op">,</span><span class="dt">sfdp</span><span class="op">,</span><span class="dt">circo</span><span class="op">,</span><span class="dt">twopi</span><span class="op">,</span><span class="dt">osage</span><span class="op">,</span><span class="dt">grid}</span></span>
<span id="cb7-43"><a href="#cb7-43" aria-hidden="true" tabindex="-1"></a> <span class="ex">SVG</span> layout engine <span class="er">(</span><span class="ex">auto</span> tries fast-sugiyama, then graphviz dot, then a simple grid<span class="kw">)</span><span class="bu">.</span></span>
<span id="cb7-44"><a href="#cb7-44" aria-hidden="true" tabindex="-1"></a> <span class="ex">--title</span> TITLE Title to embed in the generated Markdown output.</span>
<span id="cb7-45"><a href="#cb7-45" aria-hidden="true" tabindex="-1"></a> <span class="ex">--p4port</span> P4PORT Perforce server port to use for live data collection.</span>
<span id="cb7-46"><a href="#cb7-46" aria-hidden="true" tabindex="-1"></a> <span class="ex">--p4user</span> P4USER Perforce user to use for live data collection.</span></code></pre></div>
<p>If you just run it then it defaults to writing the various output
files using your current P4PORT and P4USER environment settings.</p>
<h3 id="example-output">Example output</h3>
<p>Produced from: <a
href="images/p4_topology.svg">p4_topology.svg</a></p>
<figure>
<img src="images/p4_topology.png"
alt="Example of diagram produced in SVG and lightly re-ordered and saved" />
<figcaption aria-hidden="true">Example of diagram produced in SVG and
lightly re-ordered and saved</figcaption>
</figure>
</body>
</html>