I'm not quite sure where to start, so apologies if this reply takes some random turns.
Are you ok with taking this approach:
I'm not sure how much you care about the completeness of your logging solution, but since you're dealing with scripts it's easy to get around that - instead of:
g.V().out()
someone just needs to send:
g.V().out().toList()
and they've bypassed your logging because that script will evaluate to List and not Traversal. Even without scripts, do you care that path() will return nothing for:
g.V().has('name','josh').out().drop().path()
I'm sure there are other situations like that where path() really won't help you, but perhaps you've thought that part through and are ok with your solution.
I think that there's a lot of cost to the approach you've taken, because it forces every traversal to get executed twice and even "fast" ones will then gain the burden of having to track path data which will hurt how quickly you're getting results (i guess you're doing that logging async, but i could imagine that process backing up to some degree).
That said, I'm not sure what you should do exactly. I want to suggest you write a custom TraversalStrategy that could inject logger steps of some sort into the traversal. Like, if you only cared about vertices/edges, just search for the various steps that return those types and inject a sideEfffect() that does your logging (or perhaps if you're going that far, you might create your own LogStep or perhaps you do a DSL for the log() step ???) - in other words, you convert something like:
g.V().has('name','josh').outE().has('weight',gt(0.1)).inV().out()
to
g.V().has('name','josh').log().outE().has('weight',gt(0.1)).log().inV().out().log()
and then as each traverser passes through you somehow coordinate the logging of traversed elements?? If you took the TraversalStrategy approach, your "g" would be more fool-proof to some degree as it would take someone unregistering your custom strategy to get rid of the logging but I think that could be mitigated if you needed to with sandboxing. The toList() iteration and drop() examples I used above would no longer be problems as well as a whole host of other holes. Anyway....I think i'd try to do this kind of thing at a lower level than Gremlin Server if i could.
As for your specific questions: