fio: flush log files on test end
[fio.git] / stat.c
diff --git a/stat.c b/stat.c
index ac5ff162acc4f6c8d93ee56cf7b0b16fe30fd1db..bc01b5192f31a25299591b5a66dd4c0a6d3ce242 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -497,7 +497,6 @@ static void show_latencies(struct thread_stat *ts)
        show_lat_m(io_u_lat_m);
 }
 
-
 void show_thread_status_normal(struct thread_stat *ts, struct group_run_stats *rs)
 {
        double usr_cpu, sys_cpu;
@@ -587,6 +586,13 @@ void show_thread_status_normal(struct thread_stat *ts, struct group_run_stats *r
                                        ts->first_error,
                                        strerror(ts->first_error));
        }
+       if (ts->latency_depth) {
+               log_info("     latency   : target=%llu, window=%llu, percentile=%.2f%%, depth=%u\n",
+                                       (unsigned long long)ts->latency_target,
+                                       (unsigned long long)ts->latency_window,
+                                       ts->latency_percentile.u.f,
+                                       ts->latency_depth);
+       }
 }
 
 static void show_ddir_status_terse(struct thread_stat *ts,
@@ -975,6 +981,13 @@ static struct json_object *show_thread_status_json(struct thread_stat *ts,
                json_object_add_value_int(root, "first_error", ts->first_error);
        }
 
+       if (ts->latency_depth) {
+               json_object_add_value_int(root, "latency_depth", ts->latency_depth);
+               json_object_add_value_int(root, "latency_target", ts->latency_target);
+               json_object_add_value_float(root, "latency_percentile", ts->latency_percentile.u.f);
+               json_object_add_value_int(root, "latency_window", ts->latency_window);
+       }
+
        /* Additional output if description is set */
        if (strlen(ts->description))
                json_object_add_value_string(root, "desc", ts->description);
@@ -1265,6 +1278,11 @@ static void __show_run_stats(void)
                        }
                }
 
+               ts->latency_depth = td->latency_qd;
+               ts->latency_target = td->o.latency_target;
+               ts->latency_percentile = td->o.latency_percentile;
+               ts->latency_window = td->o.latency_window;
+
                sum_thread_stats(ts, &td->ts, idx);
        }
 
@@ -1368,6 +1386,16 @@ static void __show_run_stats(void)
                show_idle_prof_stats(FIO_OUTPUT_NORMAL, NULL);
        }
 
+       if ( !(output_format == FIO_OUTPUT_TERSE) && append_terse_output) {
+               log_info("\nAdditional Terse Output:\n");
+
+               for (i = 0; i < nr_ts; i++) {
+                       ts = &threadstats[i];
+                       rs = &runstats[ts->groupid];
+                       show_thread_status_terse(ts, rs);
+               }
+       }
+
        log_info_flush();
        free(runstats);
        free(threadstats);
@@ -1551,6 +1579,37 @@ static inline void reset_io_stat(struct io_stat *ios)
        ios->mean.u.f = ios->S.u.f = 0;
 }
 
+static void _add_stat_to_log(struct io_log *iolog, unsigned long elapsed)
+{
+       /*
+        * Note an entry in the log. Use the mean from the logged samples,
+        * making sure to properly round up. Only write a log entry if we
+        * had actual samples done.
+        */
+       if (iolog->avg_window[DDIR_READ].samples) {
+               unsigned long mr;
+
+               mr = iolog->avg_window[DDIR_READ].mean.u.f + 0.50;
+               __add_log_sample(iolog, mr, DDIR_READ, 0, elapsed);
+       }
+       if (iolog->avg_window[DDIR_WRITE].samples) {
+               unsigned long mw;
+
+               mw = iolog->avg_window[DDIR_WRITE].mean.u.f + 0.50;
+               __add_log_sample(iolog, mw, DDIR_WRITE, 0, elapsed);
+       }
+       if (iolog->avg_window[DDIR_TRIM].samples) {
+               unsigned long mw;
+
+               mw = iolog->avg_window[DDIR_TRIM].mean.u.f + 0.50;
+               __add_log_sample(iolog, mw, DDIR_TRIM, 0, elapsed);
+       }
+
+       reset_io_stat(&iolog->avg_window[DDIR_READ]);
+       reset_io_stat(&iolog->avg_window[DDIR_WRITE]);
+       reset_io_stat(&iolog->avg_window[DDIR_TRIM]);
+}
+
 static void add_log_sample(struct thread_data *td, struct io_log *iolog,
                           unsigned long val, enum fio_ddir ddir,
                           unsigned int bs)
@@ -1584,35 +1643,27 @@ static void add_log_sample(struct thread_data *td, struct io_log *iolog,
        if (this_window < iolog->avg_msec)
                return;
 
-       /*
-        * Note an entry in the log. Use the mean from the logged samples,
-        * making sure to properly round up. Only write a log entry if we
-        * had actual samples done.
-        */
-       if (iolog->avg_window[DDIR_READ].samples) {
-               unsigned long mr;
-
-               mr = iolog->avg_window[DDIR_READ].mean.u.f + 0.50;
-               __add_log_sample(iolog, mr, DDIR_READ, 0, elapsed);
-       }
-       if (iolog->avg_window[DDIR_WRITE].samples) {
-               unsigned long mw;
+       _add_stat_to_log(iolog, elapsed);
 
-               mw = iolog->avg_window[DDIR_WRITE].mean.u.f + 0.50;
-               __add_log_sample(iolog, mw, DDIR_WRITE, 0, elapsed);
-       }
-       if (iolog->avg_window[DDIR_TRIM].samples) {
-               unsigned long mw;
+       iolog->avg_last = elapsed;
+}
 
-               mw = iolog->avg_window[DDIR_TRIM].mean.u.f + 0.50;
-               __add_log_sample(iolog, mw, DDIR_TRIM, 0, elapsed);
-       }
+void finalize_logs(struct thread_data *td)
+{
+       unsigned long elapsed;
 
+       elapsed = mtime_since_now(&td->epoch);
 
-       reset_io_stat(&iolog->avg_window[DDIR_READ]);
-       reset_io_stat(&iolog->avg_window[DDIR_WRITE]);
-       reset_io_stat(&iolog->avg_window[DDIR_TRIM]);
-       iolog->avg_last = elapsed;
+       if (td->clat_log)
+               _add_stat_to_log(td->clat_log, elapsed);
+       if (td->slat_log)
+               _add_stat_to_log(td->slat_log, elapsed);
+       if (td->lat_log)
+               _add_stat_to_log(td->lat_log, elapsed);
+       if (td->bw_log)
+               _add_stat_to_log(td->bw_log, elapsed);
+       if (td->iops_log)
+               _add_stat_to_log(td->iops_log, elapsed);
 }
 
 void add_agg_sample(unsigned long val, enum fio_ddir ddir, unsigned int bs)