I have seen in the past people associating log entries on thread ID; an imperfect solution, but one that worked in many cases. Having started doing async programming in c#, I am curious what is the best way to handle logging across multiple async operations. So an example:
async Task<string> GetSongNameAsync(byte [] songBytes, AuthInfo auth)
{    
    Log("Received request from user " + auth.User);
    if (!await Authentication.HasPremiumAccountAsync(auth)) // More logging in here
    {
        return "Error: Your subscription does not support this feature";
    }
    Song song = await SongIdentifier.IdentifyAsync(songBytes); // Even more logging here
    if (song != null)
    {
        return song.ToString()
    }
    return new Song() {Name = "Never Gonna Give You Up", Artist = "Rick Astley", Notes = "You just got rick-rolled!"};
}
If there is an error in the auth logic or the song ID logic, I'd like to associate the error with the particular request, so that I can query my logging database and see somewhat-sequentially how the request was handled, and maybe why it failed. I could start passing around a Guid or something like that, and include that in the message, but it seems somewhat cumbersome to make every constructor and object expose this value, when I really want it at the async equivalent of 'thread local storage'.