Files
s390-tools/ziomon/ziorep_printers.hpp
Fedor Loshakov cf7060ea08 ziomon/ziorep_utilization: add pchid column to physical adapter report
In ziorep_utilization tool physical adapter report represents PCHID
scope, rather than CHPID. PCHID column is added as a very first column of
physical adapter report for non-CSV format report.

Old version of physical adapter report with CHPID column only
looks like:
...
CHP|adapter in %-|--bus in %---|--cpu in %---|
 ID min max   avg min max   avg min max   avg
2020-05-14 14:00:41
 60   0   0   0.0   1   1   1.0   0   0   0.0
 61   0   0   0.0   1   1   1.0   0   0   0.0
...

New version of physical adapter report with additional PCHID column
looks like:
...
PCH |CHP|adapter in %-|--bus in %---|--cpu in %---|
 ID   ID min max   avg min max   avg min max   avg
2020-05-14 14:00:41
01c0  60   0   0   0.0   1   1   1.0   0   0   0.0
01c1  61   0   0   0.0   1   1   1.0   0   0   0.0
...

For CSV-format report PCHID column is appended to the end of each record line.

For older kernel releases, where PCHID sysfs entry is not available, replace
PCHID column value with "n/a".

Signed-off-by: Fedor Loshakov <loshakov@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Sakshi Singh <005c7w@linux.ibm.com>
Reviewed-by: M Nikhil <nikh1092@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2024-12-13 16:26:35 +01:00

230 lines
7.0 KiB
C++

/*
* FCP report generators
*
* Utility classes to print framsets
*
* Copyright IBM Corp. 2008, 2024
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef ZIOREP_PRINTERS
#define ZIOREP_PRINTERS
#include "ziorep_frameset.hpp"
#include "ziorep_framer.hpp"
#include "ziorep_cfgreader.hpp"
/**
* Base class for all printer classes
*/
class Printer {
public:
Printer(const ConfigReader *cfg, bool csv_mode);
virtual ~Printer() {};
/**
* Print topline to fp.
* Returns number of characters printed or <0 in case of error */
virtual void print_topline(FILE *fp) = 0;
/**
* Print frameset to fp.
* Returns number of characters printed or <0 in case of error */
virtual int print_frame(FILE *fp, const Frameset &frameset,
const DeviceFilter &dev_filt) = 0;
/// Whether the output should be done in CSV format or not
bool print_csv() const;
protected:
/**
* Print timestamp before the actual frame is printed.
* Returns number of characters printed or <0 in case of error */
void print_timestamp(FILE *fp, const Frameset &frameset);
const ConfigReader *m_cfg;
/**
* Print a given number 'num' in 'num_digs' characters with
* as many decimal places as possible.
* NOTE: max_digits must be 4 or 5!
* E.g. print_abbrev_num(13400, 5) returns '13.4K'.
*/
void print_abbrev_num(FILE *fp, __u64 num, int max_digs) const;
void print_abbrev_num(FILE *fp, __u32 num, int max_digs) const;
/**
* Print floats always using 6 characters */
void print_abbrev_num(FILE *fp, double num) const;
void print_abbrev_num(FILE *fp, double num, int max_digs,
bool more_places = false) const;
const struct adapter_utilization* get_empty_utilization(__u32 host_id);
const struct adapter_utilization* get_invalid_utilization(__u32 host_id);
const struct ioerr_cnt* get_empty_ioerr(struct hctl_ident *identifier);
const struct zfcpdd_dstat* get_empty_zfcpdd_dstat(__u32 device = 0);
const struct blkiomon_stat* get_empty_blkiomon_stat(__u32 device = 0);
/** Print the delimiter appropriate for the output. That's usually
* a space for regular output and ',' for CSV. */
inline void print_delimiter(FILE *fp);
/// Print a character indicating that the respective value is not valid
inline void print_invalid(FILE *fp, int width);
/// set if result should be printed is csv
bool m_csv;
char m_delim;
private:
void print_abbreviated(FILE *fp, double num, int leading_places,
int max_digs) const;
void determine_mag_factor(int leading_places, char *magnitude,
double *factor) const;
void determine_digs(int leading_places, int max_digs,
int *num_full_digs, int *num_places) const;
struct adapter_utilization m_util;
struct adapter_utilization m_util_invalid;
struct ioerr_cnt m_ioerr;
struct zfcpdd_dstat m_dstat;
struct blkiomon_stat m_stat;
/// day of month of last day that was printed
int m_prev_day;
};
class PhysAdapterPrinter : public Printer {
public:
PhysAdapterPrinter(const ConfigReader *cfg, bool csv_mode);
virtual void print_topline(FILE *fp);
virtual int print_frame(FILE *fp, const Frameset &frameset,
const DeviceFilter &dev_filt);
private:
void print_phys_adpt(FILE *fp, __u32 host_id,
int *rc);
void print_pchid(FILE *fp, __u32 host_id,
int *rc);
void print_utilization(FILE *fp, const struct abbrev_stat *stat,
__u64 count, bool valid);
};
class VirtAdapterPrinter : public Printer {
public:
VirtAdapterPrinter(const ConfigReader *cfg, bool csv_mode);
virtual void print_topline(FILE *fp);
virtual int print_frame(FILE *fp, const Frameset &frameset,
const DeviceFilter &dev_filt);
private:
void print_virt_adpt(FILE *fp, __u32 subchnl, int *rc);
void print_queue_fill(FILE *fp, const struct zfcpdd_dstat *stat,
const struct adapter_utilization *res);
void print_queue_full(FILE *fp, const struct adapter_utilization *res);
void print_failures(FILE *fp, const struct ioerr_cnt *cnt);
void print_throughput(FILE *fp, const struct blkiomon_stat *stat,
const __u64 interval);
void print_num_requests(FILE *fp, const struct blkiomon_stat *stat);
};
class TrafficPrinter : public Printer {
public:
virtual int print_frame(FILE *fp, const Frameset &frameset,
const DeviceFilter &dev_filt);
protected:
TrafficPrinter(const ConfigReader *cfg, Collapser &col,
bool csv_mode);
virtual ~TrafficPrinter();
/**
* Print the actual row, excluding the first column */
virtual void print_data_row(FILE *fp,
const struct blkiomon_stat *blk_stat,
const struct zfcpdd_dstat *zfcp_stat,
const __u64 interval) = 0;
void print_topline_prefix1(FILE *fp);
void print_topline_prefix2(FILE *fp);
void print_topline_whitespace(FILE *fp);
void get_device_list(list<__u64> &lst, const DeviceFilter &dev_filt);
void get_device_list(list<__u32> &lst, const DeviceFilter &dev_filt);
void print_device_wwpn(FILE *fp, __u64 wwpn);
void print_device_chpid(FILE *fp, __u32 chpid);
void print_device_devno(FILE *fp, __u32 devno);
void print_device_mp_mm(FILE *fp, __u32 mp_mm,
const ConfigReader &cfg,
int *rc);
void print_device(FILE *fp, __u32 dev,
const ConfigReader &cfg,
int *rc);
void print_device_all(FILE *fp);
Aggregator m_agg_crit;
/// Multipath devices have variable length
char *m_mp_whitespace;
char *m_mp_topline_pref1;
char *m_mp_topline_pref2;
};
class SummaryTrafficPrinter : public TrafficPrinter {
public:
SummaryTrafficPrinter(const ConfigReader *cfg,
Collapser &col, bool csv_mode);
virtual void print_topline(FILE *fp);
private:
virtual void print_data_row(FILE *fp,
const struct blkiomon_stat *blk_stat,
const struct zfcpdd_dstat *zfcp_stat,
const __u64 interval);
void print_throughput(FILE *fp, const struct blkiomon_stat *stat,
const __u64 interval);
void print_request_stats(FILE *fp, const struct blkiomon_stat *stat);
void print_io_subsystem_latency(FILE *fp, const struct blkiomon_stat *stat);
void print_channel_latency(FILE *fp, const struct zfcpdd_dstat *stat);
void print_fabric_latency(FILE *fp, const struct zfcpdd_dstat *stat);
void print_latency(FILE *fp, const struct minmax *data);
void print_latency(FILE *fp, const struct abbrev_stat *data,
__u64 count);
};
class DetailedTrafficPrinter : public TrafficPrinter {
public:
DetailedTrafficPrinter(const ConfigReader *cfg, Collapser &col,
bool csv_mode);
virtual void print_topline(FILE *fp);
private:
virtual void print_data_row(FILE *fp,
const struct blkiomon_stat *blk_stat,
const struct zfcpdd_dstat *zfcp_stat,
const __u64 interval);
void print_histogram_io_reqs(FILE *fp,
const struct blkiomon_stat *stat);
void print_histogram_io_subs_lat(FILE *fp,
const struct blkiomon_stat *stat);
void print_histogram_channel_lat(FILE *fp,
const struct zfcpdd_dstat *stat);
void print_histogram_fabric_lat(FILE *fp,
const struct zfcpdd_dstat *stat);
};
#endif