19 m_slow_duration(std::chrono::seconds(1))
21 m_log.
Say(
"------ Initializing the storage statistics plugin.");
23 throw std::runtime_error(
"Failed to configure the storage statistics plugin.");
27 if ((rc =
XrdSysThread::Run(&tid, StatsFileSystem::AggregateBootstrap,
static_cast<void *
>(
this), 0,
"FS Stats Compute Thread"))) {
28 m_log.
Emsg(
"StatsFileSystem", rc,
"create stats compute thread");
29 throw std::runtime_error(
"Failed to create the statistics computing thread.");
37 m_log.
Say(
"Config",
"Stats monitoring has been configured via xrootd.mongstream directive");
39 throw std::runtime_error(
"XrdOssStats plugin is loaded but it requires the oss monitoring g-stream to also be enabled to be set; try adding `xrootd.mongstream oss ...` to your configuration");
42 throw std::runtime_error(
"XrdOssStats plugin invoked without a configured environment; likely an internal error");
49 StatsFileSystem::AggregateBootstrap(
void *me) {
52 std::this_thread::sleep_for(std::chrono::seconds(1));
53 myself->AggregateStats();
66 m_log.
Emsg(
"Config", -result,
"parsing config file", configfn);
73 if (!strcmp(val,
"trace")) {
76 m_log.
Emsg(
"Config",
"fsstats.trace requires an argument. Usage: fsstats.trace [all|err|warning|info|debug|none]");
85 else if (!strcmp(val,
"none")) {m_log.
setMsgMask(0);}
86 }
while ((val = statsConf.
GetToken()));
87 }
else if (!strcmp(val,
"slowop")) {
89 m_log.
Emsg(
"Config",
"fsstats.slowop requires an argument. Usage: fsstats.slowop [duration]");
94 m_log.
Emsg(
"Config",
"fsstats.slowop couldn't parse duration", val, errmsg.c_str());
115 return new StatsFile(std::move(wrapped), m_log, *
this);
120 OpTimer op(m_ops.m_chmod_ops, m_slow_ops.m_chmod_ops, m_times.m_chmod, m_slow_times.m_chmod, m_slow_duration);
127 OpTimer op(m_ops.m_rename_ops, m_slow_ops.m_rename_ops, m_times.m_rename, m_slow_times.m_rename, m_slow_duration);
134 OpTimer op(m_ops.m_stat_ops, m_slow_ops.m_stat_ops, m_times.m_stat, m_slow_times.m_stat, m_slow_duration);
141 OpTimer op(m_ops.m_stat_ops, m_slow_ops.m_stat_ops, m_times.m_stat, m_slow_times.m_stat, m_slow_duration);
146 char *buff,
int &blen)
148 OpTimer op(m_ops.m_stat_ops, m_slow_ops.m_stat_ops, m_times.m_stat, m_slow_times.m_stat, m_slow_duration);
154 OpTimer op(m_ops.m_stat_ops, m_slow_ops.m_stat_ops, m_times.m_stat, m_slow_times.m_stat, m_slow_duration);
160 OpTimer op(m_ops.m_stat_ops, m_slow_ops.m_stat_ops, m_times.m_stat, m_slow_times.m_stat, m_slow_duration);
166 OpTimer op(m_ops.m_stat_ops, m_slow_ops.m_stat_ops, m_times.m_stat, m_slow_times.m_stat, m_slow_duration);
173 OpTimer op(m_ops.m_stat_ops, m_slow_ops.m_stat_ops, m_times.m_stat, m_slow_times.m_stat, m_slow_duration);
180 OpTimer op(m_ops.m_stat_ops, m_slow_ops.m_stat_ops, m_times.m_stat, m_slow_times.m_stat, m_slow_duration);
187 OpTimer op(m_ops.m_truncate_ops, m_slow_ops.m_truncate_ops, m_times.m_truncate, m_slow_times.m_truncate, m_slow_duration);
193 OpTimer op(m_ops.m_unlink_ops, m_slow_ops.m_unlink_ops, m_times.m_unlink, m_slow_times.m_unlink, m_slow_duration);
197 void StatsFileSystem::AggregateStats()
200 auto len = snprintf(buf, 1500,
202 "\"event\":\"oss_stats\"," \
203 "\"reads\":%" PRIu64
",\"writes\":%" PRIu64
",\"stats\":%" PRIu64
"," \
204 "\"pgreads\":%" PRIu64
",\"pgwrites\":%" PRIu64
",\"readvs\":%" PRIu64
"," \
205 "\"readv_segs\":%" PRIu64
",\"dirlists\":%" PRIu64
",\"dirlist_ents\":%" PRIu64
","
206 "\"truncates\":%" PRIu64
",\"unlinks\":%" PRIu64
",\"chmods\":%" PRIu64
","
207 "\"opens\":%" PRIu64
",\"renames\":%" PRIu64
","
208 "\"slow_reads\":%" PRIu64
",\"slow_writes\":%" PRIu64
",\"slow_stats\":%" PRIu64
","
209 "\"slow_pgreads\":%" PRIu64
",\"slow_pgwrites\":%" PRIu64
",\"slow_readvs\":%" PRIu64
","
210 "\"slow_readv_segs\":%" PRIu64
",\"slow_dirlists\":%" PRIu64
",\"slow_dirlist_ents\":%" PRIu64
","
211 "\"slow_truncates\":%" PRIu64
",\"slow_unlinks\":%" PRIu64
",\"slow_chmods\":%" PRIu64
","
212 "\"slow_opens\":%" PRIu64
",\"slow_renames\":%" PRIu64
","
213 "\"open_t\":%.4f,\"read_t\":%.4f,\"readv_t\":%.4f,"
214 "\"pgread_t\":%.4f,\"write_t\":%.4f,\"pgwrite_t\":%.4f,"
215 "\"dirlist_t\":%.4f,\"stat_t\":%.4f,\"truncate_t\":%.4f,"
216 "\"unlink_t\":%.4f,\"rename_t\":%.4f,\"chmod_t\":%.4f,"
217 "\"slow_open_t\":%.4f,\"slow_read_t\":%.4f,\"slow_readv_t\":%.4f,"
218 "\"slow_pgread_t\":%.4f,\"slow_write_t\":%.4f,\"slow_pgwrite_t\":%.4f,"
219 "\"slow_dirlist_t\":%.4f,\"slow_stat_t\":%.4f,\"slow_truncate_t\":%.4f,"
220 "\"slow_unlink_t\":%.4f,\"slow_rename_t\":%.4f,\"slow_chmod_t\":%.4f"
222 m_ops.m_read_ops.load(), m_ops.m_write_ops.load(), m_ops.m_stat_ops.load(),
223 m_ops.m_pgread_ops.load(), m_ops.m_pgwrite_ops.load(), m_ops.m_readv_ops.load(),
224 m_ops.m_readv_segs.load(), m_ops.m_dirlist_ops.load(), m_ops.m_dirlist_entries.load(),
225 m_ops.m_truncate_ops.load(), m_ops.m_unlink_ops.load(), m_ops.m_chmod_ops.load(),
226 m_ops.m_open_ops.load(), m_ops.m_rename_ops.load(),
227 m_slow_ops.m_read_ops.load(), m_slow_ops.m_write_ops.load(), m_slow_ops.m_stat_ops.load(),
228 m_slow_ops.m_pgread_ops.load(), m_slow_ops.m_pgwrite_ops.load(), m_slow_ops.m_readv_ops.load(),
229 m_slow_ops.m_readv_segs.load(), m_slow_ops.m_dirlist_ops.load(), m_slow_ops.m_dirlist_entries.load(),
230 m_slow_ops.m_truncate_ops.load(), m_slow_ops.m_unlink_ops.load(), m_slow_ops.m_chmod_ops.load(),
231 m_slow_ops.m_open_ops.load(), m_slow_ops.m_rename_ops.load(),
232 static_cast<float>(m_times.m_open.load())/1e9,
static_cast<float>(m_times.m_read.load())/1e9,
static_cast<float>(m_times.m_readv.load())/1e9,
233 static_cast<float>(m_times.m_pgread.load())/1e9,
static_cast<float>(m_times.m_write.load())/1e9,
static_cast<float>(m_times.m_pgwrite.load())/1e9,
234 static_cast<float>(m_times.m_dirlist.load())/1e9,
static_cast<float>(m_times.m_stat.load())/1e9,
static_cast<float>(m_times.m_truncate.load())/1e9,
235 static_cast<float>(m_times.m_unlink.load())/1e9,
static_cast<float>(m_times.m_rename.load())/1e9,
static_cast<float>(m_times.m_chmod.load())/1e9,
236 static_cast<float>(m_slow_times.m_open.load())/1e9,
static_cast<float>(m_slow_times.m_read.load())/1e9,
static_cast<float>(m_slow_times.m_readv.load())/1e9,
237 static_cast<float>(m_slow_times.m_pgread.load())/1e9,
static_cast<float>(m_slow_times.m_write.load())/1e9,
static_cast<float>(m_slow_times.m_pgwrite.load())/1e9,
238 static_cast<float>(m_slow_times.m_dirlist.load())/1e9,
static_cast<float>(m_slow_times.m_stat.load())/1e9,
static_cast<float>(m_slow_times.m_truncate.load())/1e9,
239 static_cast<float>(m_slow_times.m_unlink.load())/1e9,
static_cast<float>(m_slow_times.m_rename.load())/1e9,
static_cast<float>(m_slow_times.m_chmod.load())/1e9
243 m_log.
Log(
LogMask::Error,
"Aggregate",
"Failed to generate g-stream statistics packet");
247 if (m_gstream && !m_gstream->
Insert(buf, len + 1)) {
248 m_log.
Log(
LogMask::Error,
"Aggregate",
"Failed to send g-stream statistics packet");
253 StatsFileSystem::OpTimer::OpTimer(std::atomic<uint64_t> &op_count, std::atomic<uint64_t> &slow_op_count, std::atomic<uint64_t> &timing, std::atomic<uint64_t> &slow_timing, std::chrono::steady_clock::duration duration)
254 : m_op_count(op_count),
255 m_slow_op_count(slow_op_count),
257 m_slow_timing(slow_timing),
258 m_start(std::chrono::steady_clock::now()),
259 m_slow_duration(duration)
262 StatsFileSystem::OpTimer::~OpTimer()
264 auto dur = std::chrono::steady_clock::now() - m_start;
266 m_timing += std::chrono::nanoseconds(dur).count();
267 if (dur > m_slow_duration) {
269 m_slow_timing += std::chrono::nanoseconds(dur).count();
bool ParseDuration(const std::string &duration, std::chrono::steady_clock::duration &result, std::string &errmsg)
std::string LogMaskToString(int mask)
int stat(const char *path, struct stat *buf)
XrdOssDF * newDir(const char *user=0) override
StatsFileSystem(XrdOss *oss, XrdSysLogger *log, const char *configName, XrdOucEnv *envP)
int Stat(const char *path, struct stat *buff, int opts=0, XrdOucEnv *env=0) override
int StatXP(const char *path, unsigned long long &attr, XrdOucEnv *env=0) override
virtual ~StatsFileSystem()
int StatFS(const char *path, char *buff, int &blen, XrdOucEnv *env=0) override
XrdOssDF * newFile(const char *user=0) override
friend class StatsDirectory
bool Config(const char *configfn)
int StatPF(const char *path, struct stat *buff, int opts) override
int StatLS(XrdOucEnv &env, const char *path, char *buff, int &blen) override
int Unlink(const char *path, int Opts=0, XrdOucEnv *env=0) override
int Chmod(const char *path, mode_t mode, XrdOucEnv *env=0) override
int StatVS(XrdOssVSInfo *vsP, const char *sname=0, int updt=0) override
int Truncate(const char *path, unsigned long long fsize, XrdOucEnv *env=0) override
int StatXA(const char *path, char *buff, int &blen, XrdOucEnv *env=0) override
int Rename(const char *oPath, const char *nPath, XrdOucEnv *oEnvP=0, XrdOucEnv *nEnvP=0) override
virtual int StatLS(XrdOucEnv &env, const char *path, char *buff, int &blen)
virtual int StatXA(const char *path, char *buff, int &blen, XrdOucEnv *envP=0)
virtual int StatXP(const char *path, unsigned long long &attr, XrdOucEnv *envP=0)
virtual XrdOssDF * newDir(const char *tident)=0
virtual int Chmod(const char *path, mode_t mode, XrdOucEnv *envP=0)=0
virtual int StatPF(const char *path, struct stat *buff, int opts)
virtual int StatVS(XrdOssVSInfo *vsP, const char *sname=0, int updt=0)
virtual int StatFS(const char *path, char *buff, int &blen, XrdOucEnv *envP=0)
virtual int Rename(const char *oPath, const char *nPath, XrdOucEnv *oEnvP=0, XrdOucEnv *nEnvP=0)=0
virtual XrdOssDF * newFile(const char *tident)=0
virtual int Truncate(const char *path, unsigned long long fsize, XrdOucEnv *envP=0)=0
virtual int Stat(const char *path, struct stat *buff, int opts=0, XrdOucEnv *envP=0)=0
virtual int Unlink(const char *path, int Opts=0, XrdOucEnv *envP=0)=0
void * GetPtr(const char *varname)
char * GetToken(char **rest=0, int lowcase=0)
int Gather(const char *cfname, Level lvl, const char *parms=0)
@ trim_lines
Prefix trimmed lines.
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
void setMsgMask(int mask)
void Log(int mask, const char *esfx, const char *text1, const char *text2=0, const char *text3=0)
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
bool Insert(const char *data, int dlen)