]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/LogMonitor: make 'ceph log last' work with new storage 42014/head
authorSage Weil <sage@newdream.net>
Thu, 24 Jun 2021 16:25:11 +0000 (12:25 -0400)
committerSage Weil <sage@newdream.net>
Sat, 3 Jul 2021 18:29:40 +0000 (14:29 -0400)
Signed-off-by: Sage Weil <sage@newdream.net>
src/mon/LogMonitor.cc

index 20c9bcd1f162dfd4a93c8c34e6ff90296fd6a1dc..33f3e9d07fcdad7591b819422d1b485f8e12e77c 100644 (file)
@@ -811,78 +811,155 @@ bool LogMonitor::preprocess_command(MonOpRequestRef op)
       return entry.prio >= level;
     };
 
-    // Decrement operation that sets to container end when hitting rbegin
     ostringstream ss;
-    if (channel == "*") {
-      list<LogEntry> full_tail;
-      summary.build_ordered_tail_legacy(&full_tail);
-      auto rp = full_tail.rbegin();
-      for (; num > 0 && rp != full_tail.rend(); ++rp) {
-       if (match(*rp)) {
-         num--;
+    if (!summary.tail_by_channel.empty()) {
+      // pre-quincy compat
+      // Decrement operation that sets to container end when hitting rbegin
+      if (channel == "*") {
+       list<LogEntry> full_tail;
+       summary.build_ordered_tail_legacy(&full_tail);
+       auto rp = full_tail.rbegin();
+       for (; num > 0 && rp != full_tail.rend(); ++rp) {
+         if (match(*rp)) {
+           num--;
+         }
+       }
+       if (rp == full_tail.rend()) {
+         --rp;
        }
-      }
-      if (rp == full_tail.rend()) {
-       --rp;
-      }
 
-      // Decrement a reverse iterator such that going past rbegin()
-      // sets it to rend().  This is for writing a for() loop that
-      // goes up to (and including) rbegin()
-      auto dec = [&rp, &full_tail] () {
-        if (rp == full_tail.rbegin()) {
-          rp = full_tail.rend();
-        } else {
-          --rp;
-        }
-      };
-
-      // Move forward to the end of the container (decrement the reverse
-      // iterator).
-      for (; rp != full_tail.rend(); dec()) {
-       if (!match(*rp)) {
-         continue;
+       // Decrement a reverse iterator such that going past rbegin()
+       // sets it to rend().  This is for writing a for() loop that
+       // goes up to (and including) rbegin()
+       auto dec = [&rp, &full_tail] () {
+                    if (rp == full_tail.rbegin()) {
+                      rp = full_tail.rend();
+                    } else {
+                      --rp;
+                    }
+                  };
+
+       // Move forward to the end of the container (decrement the reverse
+       // iterator).
+       for (; rp != full_tail.rend(); dec()) {
+         if (!match(*rp)) {
+           continue;
+         }
+         if (f) {
+           f->dump_object("entry", *rp);
+         } else {
+           ss << *rp << "\n";
+         }
        }
-       if (f) {
-         f->dump_object("entry", *rp);
-       } else {
-         ss << *rp << "\n";
+      } else {
+       auto p = summary.tail_by_channel.find(channel);
+       if (p != summary.tail_by_channel.end()) {
+         auto rp = p->second.rbegin();
+         for (; num > 0 && rp != p->second.rend(); ++rp) {
+           if (match(rp->second)) {
+             num--;
+           }
+         }
+         if (rp == p->second.rend()) {
+           --rp;
+         }
+
+         // Decrement a reverse iterator such that going past rbegin()
+         // sets it to rend().  This is for writing a for() loop that
+         // goes up to (and including) rbegin()
+         auto dec = [&rp, &p] () {
+                      if (rp == p->second.rbegin()) {
+                        rp = p->second.rend();
+                      } else {
+                        --rp;
+                      }
+                    };
+         
+         // Move forward to the end of the container (decrement the reverse
+         // iterator).
+         for (; rp != p->second.rend(); dec()) {
+           if (!match(rp->second)) {
+             continue;
+           }
+           if (f) {
+             f->dump_object("entry", rp->second);
+           } else {
+             ss << rp->second << "\n";
+           }
+         }
        }
       }
     } else {
-      auto p = summary.tail_by_channel.find(channel);
-      if (p != summary.tail_by_channel.end()) {
-       auto rp = p->second.rbegin();
-       for (; num > 0 && rp != p->second.rend(); ++rp) {
-         if (match(rp->second)) {
-           num--;
+      // quincy+
+      if (channel == "*") {
+       // tail all channels; we need to mix by timestamp
+       multimap<utime_t,LogEntry> entries;  // merge+sort all channels by timestamp
+       for (auto& p : summary.channel_info) {
+         version_t from = p.second.first;
+         version_t to = p.second.second;
+         version_t start;
+         if (to > (version_t)num) {
+           start = std::max(to - num, from);
+         } else {
+           start = from;
+         }
+         dout(10) << __func__ << " channnel " << p.first
+                  << " from " << from << " to " << to << dendl;
+         for (version_t v = start; v < to; ++v) {
+           bufferlist ebl;
+           string key;
+           generate_logentry_key(p.first, v, &key);
+           int r = mon.store->get(get_service_name(), key, ebl);
+           if (r < 0) {
+             derr << __func__ << " missing key " << key << dendl;
+             continue;
+           }
+           LogEntry le;
+           auto p = ebl.cbegin();
+           decode(le, p);
+           entries.insert(make_pair(le.stamp, le));
          }
        }
-       if (rp == p->second.rend()) {
-         --rp;
+       while ((int)entries.size() > num) {
+         entries.erase(entries.begin());
        }
-
-        // Decrement a reverse iterator such that going past rbegin()
-        // sets it to rend().  This is for writing a for() loop that
-        // goes up to (and including) rbegin()
-        auto dec = [&rp, &p] () {
-          if (rp == p->second.rbegin()) {
-            rp = p->second.rend();
-          } else {
-            --rp;
-          }
-        };
-
-        // Move forward to the end of the container (decrement the reverse
-        // iterator).
-       for (; rp != p->second.rend(); dec()) {
-         if (!match(rp->second)) {
-           continue;
-         }
+       for (auto& p : entries) {
          if (f) {
-           f->dump_object("entry", rp->second);
+           f->dump_object("entry", p.second);
          } else {
-           ss << rp->second << "\n";
+           ss << p.second << "\n";
+         }
+       }
+      } else {
+       // tail one channel
+       auto p = summary.channel_info.find(channel);
+       if (p != summary.channel_info.end()) {
+         version_t from = p->second.first;
+         version_t to = p->second.second;
+         version_t start;
+         if (to > (version_t)num) {
+           start = std::max(to - num, from);
+         } else {
+           start = from;
+         }
+         dout(10) << __func__ << " from " << from << " to " << to << dendl;
+         for (version_t v = start; v < to; ++v) {
+           bufferlist ebl;
+           string key;
+           generate_logentry_key(channel, v, &key);
+           int r = mon.store->get(get_service_name(), key, ebl);
+           if (r < 0) {
+             derr << __func__ << " missing key " << key << dendl;
+             continue;
+           }
+           LogEntry le;
+           auto p = ebl.cbegin();
+           decode(le, p);
+           if (f) {
+             f->dump_object("entry", le);
+           } else {
+             ss << le << "\n";
+           }
          }
        }
       }