curl_global_trace(3)

πŸ¦‹ curl_global_trace β€” log configuration πŸ¦‹

okay bestie, welcome to the Library Functions Manual corner of the internet, because this is the curl_global_trace(3) page and it is literally the glow-up switch for how chatty libcurl gets πŸ’¬βœ¨


✨ SYNOPSIS ✨

#include <curl/curl.h>

CURLcode curl_global_trace(const char *config);

that's it. one include, one function, one string. slay πŸ’…


πŸ’– DESCRIPTION πŸ’–

so the whole vibe of this function is log configuration β€” it tunes how libcurl logs stuff so some parts of curl get more verbose and other parts get more silent than the rest. not me giving each subsystem its own volume slider 🎚️

it may be called during the initialization phase of a program. it does not have to be, bestie, no pressure. it can even be called several times, possibly overwriting the settings from previous calls β€” icon behaviour, honestly.

🚨 calling this function after transfers have been started is undefined. on some platforms/architectures it might take effect, on others not. so like… don't. periodt πŸ’€

this function is thread-safe since libcurl 8.3.0 if curl_version_info(3) has the CURL_VERSION_THREADSAFE feature bit set (which is most platforms 🌈).

if it is not thread-safe, you must not call this function while any other thread in the program (i.e. a thread sharing the same memory) is running. and no, that is not just "no other thread that is using libcurl" β€” because curl_global_init(3) may call functions of other libraries that are similarly thread-unsafe, it could conflict with any other thread that uses these other libraries. the more you know 🧠✨

if you are initializing libcurl from a Windows DLL, you should not initialize it from DllMain or a static initializer, because Windows holds the loader lock during that time and it could cause a deadlock. genuinely do not do this πŸ™ˆ


πŸ“ the config string, explained πŸ“

the config string is a list of comma-separated component names. names are case-insensitive and unknown names are ignored (silently, no drama). the special name "all" applies to all components. names may be prefixed with + or - to enable or disable detailed logging for a component. so it's giving "checkboxes but make it a string" πŸŽ€

πŸ‘‘ important lore: the list of component names is not part of curl's public API. names may be added or disappear in future versions of libcurl. but since unknown names are silently ignored, outdated log configurations don't cause errors when you upgrade libcurl. some names can be expected to be fairly stable though, and they're listed below for easy reference, iykyk πŸ’œ

also, heads up: log configuration applies only to transfers where debug logging is enabled. see CURLOPT_VERBOSE(3) or CURLOPT_DEBUGFUNCTION(3) for how to control that πŸ‘€


🌸 TRACE COMPONENTS 🌸

these are the lil' name tags you can put in your config string:

  • tcp β€” tracing of TCP socket handling: connect, sends, receives πŸ”Œ
  • ssl β€” tracing of SSL/TLS operations, whichever SSL backend is used in your build πŸ”
  • ftp β€” tracing of FTP operations when this protocol is enabled in your build πŸ“
  • http/2 β€” details about HTTP/2 handling: frames, events, I/O, etc. πŸͺŸ
  • http/3 β€” details about HTTP/3 handling: connect, frames, events, I/O etc. ⚑
  • http-proxy β€” involved when transfers are tunneled through an HTTP proxy. "h1-proxy" or "h2-proxy" are also involved, depending on the HTTP version negotiated with the proxy. πŸ›‘οΈ in order to find out all components involved in a transfer, run it with "all" configured. you can then see all names involved in your libcurl version in the trace. detective mode πŸ”
  • dns β€” tracing of DNS operations to resolve hostnames and HTTPS records 🌐
  • lib-ids β€” adds transfer and connection identifiers as prefix to every call to CURLOPT_DEBUGFUNCTION(3). the format is [n-m] where n is the identifier of the transfer and m is the identifier of the connection. a literal x is used for internal transfers or when no connection is assigned. 🏷️ for example, [5-x] is the prefix for transfer 5 that has no connection. the command line tool curl uses the same format for its --trace-ids option. lib-ids is intended for libcurl applications that handle multiple transfers but have no own way to identify in trace output which transfer a trace event is connected to. literally built for the multitaskers πŸ’…
  • doh β€” former name for DNS-over-HTTP operations. now an alias for dns. glow-up/rebrand, we love to see it ✨
  • multi β€” traces multi operations managing transfers' state changes and sockets poll states πŸ”„
  • read β€” traces reading of upload data from the application in order to send it to the server πŸ“€
  • ssh β€” tracing of SSH related protocols SCP and SFTP πŸ”‘
  • ssls β€” tracing of SSL Session handling, e.g. caching/import/export πŸ—‚οΈ
  • smtp β€” tracing of SMTP operations when this protocol is enabled in your build πŸ“§
  • timer β€” tracing of timers set for transfers ⏱️
  • write β€” traces writing of download data, received from the server, to the application πŸ“₯
  • ws β€” tracing of WebSocket operations when this protocol is enabled in your build πŸ•ΈοΈ

🫢 TRACE GROUPS 🫢

besides the specific component names, there are also these group names defined:

  • all β€” all components that your libcurl is built with πŸ‘‘
  • network β€” all components involved in bare network I/O, including the SSL layer 🌐
  • protocol β€” all components involved in transfer protocols, such as 'ftp' and 'http/2' πŸ“‘
  • proxy β€” all components involved in use of proxies πŸ›‘οΈ

🌈 PROTOCOLS 🌈

this functionality affects all supported protocols. every single one. no cap πŸ’―


🧚 EXAMPLE 🧚

int main(void)
{
  /* log details of HTTP/2 and SSL handling */
  curl_global_trace("http/2,ssl");

  /* log all details, except SSL handling */
  curl_global_trace("all,-ssl");
}

below is a trace sample where "http/2" was configured. the trace output of an enabled component appears at the beginning in brackets πŸ‘‘

* [HTTP/2] [h2sid=1] cf_send(len=96) submit https://example.com/
...
* [HTTP/2] [h2sid=1] FRAME[HEADERS]
* [HTTP/2] [h2sid=1] 249 header bytes
...

see how the [HTTP/2] tag is just sitting there, main character energy? that's the whole point πŸŽ€


⭐ AVAILABILITY ⭐

added in curl 8.3.0 β€” so if you're on something ancient, this is your sign to upgrade bestie 🫢


πŸ’œ RETURN VALUE πŸ’œ

if this function returns non-zero, something went wrong and the configuration may not have any effects, or may only have been applied partially. not the slay we wanted 😭


πŸ”₯ SEE ALSO πŸ”₯


and that's the page!! πŸ’– brought to you by libcurl, dated 2026-10-12, in the Library Functions Manual β€” go forth and trace responsibly, bestie πŸŒΈπŸ¦‹

πŸ“¦ where this page comes from