The client IP and the Shiny session token cannot be read in JavaScript, so the
server pushes them once at session start; the client then stamps them on every
queued row (the ip and session columns of cc_log_header()). Call it at
the top of the server function, before any cc_track() call, so no event
is written without them.
Details
The token is authoritative, the IP is only a fallback: behind
shiny-server a session sees 127.0.0.1, so an ip already baked into the
page by cc_ga_js() wins and this one is ignored.