sahildevgon commented on code in PR #22454:
URL: https://github.com/apache/kafka/pull/22454#discussion_r3485575900
##########
server/src/main/java/org/apache/kafka/server/metrics/LinuxIoMetricsCollector.java:
##########
@@ -35,36 +35,98 @@ public class LinuxIoMetricsCollector {
private static final Logger LOG =
LoggerFactory.getLogger(LinuxIoMetricsCollector.class);
private static final String READ_BYTES_PREFIX = "read_bytes: ";
private static final String WRITE_BYTES_PREFIX = "write_bytes: ";
+ private static final String RCHAR_PREFIX = "rchar: ";
+ private static final String WCHAR_PREFIX = "wchar: ";
+ private static final String SYSCR_PREFIX = "syscr: ";
+ private static final String SYSCW_PREFIX = "syscw: ";
+ private static final String CANCELLED_WRITE_BYTES_PREFIX =
"cancelled_write_bytes: ";
private final Time time;
private final Path path;
- private long lastUpdateMs = -1L;
- private long cachedReadBytes = 0L;
- private long cachedWriteBytes = 0L;
+ private volatile long lastUpdateMs = -1L;
+ private volatile long cachedReadBytes = 0L;
+ private volatile long cachedWriteBytes = 0L;
+ private volatile long cachedRchar = 0L;
+ private volatile long cachedWchar = 0L;
+ private volatile long cachedSyscr = 0L;
+ private volatile long cachedSyscw = 0L;
+ private volatile long cachedCancelledWriteBytes = 0L;
public LinuxIoMetricsCollector(String procRoot, Time time) {
this.time = time;
path = Paths.get(procRoot, "self", "io");
}
public long readBytes() {
- synchronized (this) {
- long curMs = time.milliseconds();
- if (curMs != lastUpdateMs) {
- updateValues(curMs);
- }
- return cachedReadBytes;
- }
+ refreshIfStale();
+ return cachedReadBytes;
}
public long writeBytes() {
- synchronized (this) {
- long curMs = time.milliseconds();
- if (curMs != lastUpdateMs) {
- updateValues(curMs);
+ refreshIfStale();
+ return cachedWriteBytes;
+ }
+
+ /**
+ * Returns the total number of characters read (includes cached reads).
+ * This value represents all read operations, including those satisfied by
the page cache.
+ */
+ public long rchar() {
+ refreshIfStale();
+ return cachedRchar;
+ }
+
+ /**
+ * Returns the total number of characters written (includes cached writes).
+ * This value represents all write operations, including those that may
not have reached disk.
+ */
+ public long wchar() {
+ refreshIfStale();
+ return cachedWchar;
+ }
+
+ /**
+ * Returns the number of read system calls.
+ * This metric helps identify I/O patterns and syscall overhead.
+ */
+ public long syscr() {
+ refreshIfStale();
+ return cachedSyscr;
+ }
+
+ /**
+ * Returns the number of write system calls.
+ * This metric helps identify I/O patterns and syscall overhead.
+ */
+ public long syscw() {
+ refreshIfStale();
+ return cachedSyscw;
+ }
+
+ /**
+ * Returns the number of bytes that were cancelled before being written.
+ * This can occur when a write is truncated or cancelled.
+ */
+ public long cancelledWriteBytes() {
+ refreshIfStale();
+ return cachedCancelledWriteBytes;
+ }
+
+ /**
+ * Refreshes all cached values from /proc/self/io if more than one
millisecond has elapsed
+ * since the last refresh. Uses double-checked locking so getters return
without acquiring
+ * the monitor in the common (cached) case — across all 7 gauges in a
single JMX scrape
+ * the lock is taken at most once per ms-window, and zero times in steady
state.
+ */
+ private void refreshIfStale() {
+ long curMs = time.milliseconds();
+ if (curMs != lastUpdateMs) {
+ synchronized (this) {
Review Comment:
@chia7712 done. refreshIfStale now uses AtomicBoolean.compareAndSet; if
another thread is mid-update, the caller falls through and reads the current
cached value (safe since updateValues never publishes intermediate -1L). Also
dropped synchronized from usable() - it's called once at construction time
before any reader threads exist, so direct invocation is fine and the volatile
writes carry happens-before to subsequent getters.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]