<p>I'm looking at the Kubernetes logs we see in our log aggregation tool (Splunk, but not important), and I'm trying to visualise image pull speeds over the day. message that appears in the logs is something like:</p>
<p>Successfully pulled image &quot;registry.redhat.io/redhat/redhat-operator-index:v4.10&quot; in 1.100152244s</p>
<p>The value 1.100152244s is a string so obviously doesn't work for visualisation. The string itself can appear in multiple formats:</p>
<p>1.100152244s
4m4.004131504s
64.10064ms</p>
<p>Silly question but what units do we see here after the period? Are these nanoseconds?</p>
<p>Many thanks in advance</p>

Michael
<p><strong>Disclaimer</strong>: At the time of writing I am not an expert on Kubernetes internals nor do I have any knowledge about Go. (However, I am familiar with the general functioning of K8s components and also with high/low level programming languages...) After about 10 min of research I've gained satisfactory answers:</p>
<p><strong>Question</strong></p>
<blockquote>
<p>what units do we see here after the period? Are these nanoseconds?</p>
</blockquote>
<p><strong>Short answer</strong></p>
<p>The short answer lies in <a href="https://github.com/golang/go/blob/master/src/time/time.go#L644" rel="nofollow noreferrer">time.go</a>.</p>
<p><strong>Long answer</strong></p>
<p>The Kubernetes event regarding &quot;<em>Successfully pulled image &lt;image-name&gt; in &lt;time&gt;</em>&quot; is generated by the <code>kubelet</code> component. <em>Kubelet</em> is basically responsible for managing (the life cycle of) pods and their containers. It generates <a href="https://github.com/kubernetes/kubernetes/blob/release-1.24/pkg/kubelet/events/event.go#L40" rel="nofollow noreferrer">events</a> for various stages of the container's execution, including the <code>image pulling</code>. Thus the event you mentioned is generated by the <em>kubelet</em> during the image pulling stage of container execution. (At least I knew that part already).</p>
<p>You seem to have a kubelet &lt;= release-1.24 in use. The corresponding event is generated <a href="https://github.com/kubernetes/kubernetes/blob/release-1.24/pkg/kubelet/images/image_manager.go#L156" rel="nofollow noreferrer">here</a>:</p>
<pre class="lang-golang prettyprint-override"><code>..., fmt.Sprintf(&quot;Successfully pulled image %q in %v&quot;, container.Image, time.Since(startTime)), ...
</code></pre>
<p>The duration string comes from the <code>time.Since(startTime)</code> (<code>Duration</code>) stament. The <code>fmt.Sprintf</code> calls the <a href="https://github.com/golang/go/blob/master/src/time/time.go#L644" rel="nofollow noreferrer"><code>func (d Duration) String() string</code></a> method on that Duration value, which appears to produce a string output according to the following criteria:</p>
<ul>
<li><p>If the duration is less than one second, it is displayed with smaller units such as &quot;12.345µs&quot; or &quot;678ns&quot;.</p>
</li>
<li><p>If the duration is between one second and one minute, it is displayed in seconds, such as &quot;5s&quot; or &quot;42.123456s&quot;.</p>
</li>
<li><p>If the duration is between one minute and one hour, it is displayed in minutes and seconds, such as &quot;3m45s&quot; or &quot;59m59s&quot;.</p>
</li>
<li><p>If the duration is more than one hour, it is displayed in hours, minutes, and seconds, such as &quot;1h42m&quot; or &quot;12h34m56s&quot;.</p>
</li>
</ul>
<p>Maybe you can develop suitable patterns in Splunk to transform this format into the desired time unit for visualization (using if-else conditions may also help, e.g. value includes &quot;h&quot;, &quot;m&quot; and &quot;s&quot;? then use the regex <code>(\d+)h(\d+)m(\d+\.?\d*)s</code> to extract values from e.g. &quot;2h10m10.100152244s&quot;).</p>
<p><strong>Side note</strong></p>
<p>Newer versions of kubelet (&gt; release-1.24) seem to use a slightly different  <a href="https://github.com/kubernetes/kubernetes/blob/release-1.25/pkg/kubelet/images/image_manager.go" rel="nofollow noreferrer">log</a></p>
<pre class="lang-golang prettyprint-override"><code>..., fmt.Sprintf(&quot;Successfully pulled image %q in %v (%v including waiting)&quot;, container.Image, imagePullResult.pullDuration, time.Since(startTime)), ...
</code></pre>
<p>e.g.</p>
<blockquote>
<p>Successfully pulled image &quot;xyz&quot; in 8.831719579s (8.831722421s including waiting)</p>
</blockquote>
