]> git.sesse.net Git - cubemap/blobdiff - stats.cpp
Keep information about HLS downloads around for some time afterwards.
[cubemap] / stats.cpp
index 5193243aafb82ab87bb6ca577a9c14ddfa5a1874..955f2e9450ebb6fc7baf73e188fc6eddf372fa62 100644 (file)
--- a/stats.cpp
+++ b/stats.cpp
@@ -31,6 +31,8 @@ void StatsThread::do_work()
                FILE *fp;
                timespec now;
                vector<ClientStats> client_stats;
+               vector<HLSZombie> hls_zombies;
+               unordered_map<string, HLSZombie> remaining_hls_zombies;
 
                if (clock_gettime(CLOCK_MONOTONIC_COARSE, &now) == -1) {
                        log_perror("clock_gettime(CLOCK_MONOTONIC_COARSE)");
@@ -57,19 +59,60 @@ void StatsThread::do_work()
                        goto sleep;
                }
 
-               client_stats = servers->get_client_stats();
-               for (size_t i = 0; i < client_stats.size(); ++i) {
+               // Get all the HLS zombies and combine them into one map (we resolve conflicts
+               // by having an arbitrary element win; in practice, that means the lowest
+               // server ID).
+               for (HLSZombie &zombie : servers->get_hls_zombies()) {
+                       const string remote_addr = zombie.remote_addr;
+                       remaining_hls_zombies[move(remote_addr)] = move(zombie);
+               }
+
+               // Remove all zombies whose ID match an already ongoing request.
+               // (Normally, this is cleared out already when it starts,
+               // but the request could happen on a different server from the zombie,
+               // or the zombie could be deserialized.)
+               for (const ClientStats &stats : servers->get_client_stats()) {
+                       if (stats.url != "-") {
+                               remaining_hls_zombies.erase(stats.hls_zombie_key);
+                       }
+               }
+
+               for (const ClientStats &stats : servers->get_client_stats()) {
+                       string url = stats.url;
+                       if (url == "-") {
+                               // No download going on currently; could it be waiting for more HLS fragments?
+                               auto it = remaining_hls_zombies.find(stats.remote_addr);
+                               if (it != remaining_hls_zombies.end()) {
+                                       url = it->second.url;
+                                       remaining_hls_zombies.erase(it);
+                               }
+                       }
+
+                       fprintf(fp, "%s %d %d %s %d %llu %llu %llu \"%s\" \"%s\"\n",
+                               stats.remote_addr.c_str(),
+                               stats.sock,
+                               0,  // Used to be fwmark.
+                               url.c_str(),
+                               int(now.tv_sec - stats.connect_time.tv_sec),  // Rather coarse.
+                               (long long unsigned)(stats.bytes_sent),
+                               (long long unsigned)(stats.bytes_lost),
+                               (long long unsigned)(stats.num_loss_events),
+                               stats.referer.c_str(),
+                               stats.user_agent.c_str());
+               }
+               for (const auto &url_and_zombie : remaining_hls_zombies) {
+                       const HLSZombie &zombie = url_and_zombie.second;
                        fprintf(fp, "%s %d %d %s %d %llu %llu %llu \"%s\" \"%s\"\n",
-                               client_stats[i].remote_addr.c_str(),
-                               client_stats[i].sock,
+                               zombie.remote_addr.c_str(),
+                               0,  // Fake socket. (The Munin script doesn't like negative numbers.)
                                0,  // Used to be fwmark.
-                               client_stats[i].url.c_str(),
-                               int(now.tv_sec - client_stats[i].connect_time.tv_sec),  // Rather coarse.
-                               (long long unsigned)(client_stats[i].bytes_sent),
-                               (long long unsigned)(client_stats[i].bytes_lost),
-                               (long long unsigned)(client_stats[i].num_loss_events),
-                               client_stats[i].referer.c_str(),
-                               client_stats[i].user_agent.c_str());
+                               zombie.url.c_str(),
+                               0,
+                               0ULL,
+                               0ULL,
+                               0ULL,
+                               zombie.referer.c_str(),
+                               zombie.user_agent.c_str());
                }
                if (fclose(fp) == EOF) {
                        log_perror("fclose");