Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Per Cederqvist
lyskom-server-ceder-1616-generations-topgit
Commits
1e0b323a
Commit
1e0b323a
authored
Jul 23, 2003
by
Per Cederqvist
Browse files
New file, that collects some statistical information about the
operation of the server.
parent
395d370f
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/server/stats.c
0 → 100644
View file @
1e0b323a
/*
* Copyright (C) 2003 Lysator Academic Computer Association.
*
* This file is part of the LysKOM server.
*
* LysKOM is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* LysKOM is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with LysKOM; see the file COPYING. If not, write to
* Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
* or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
* MA 02139, USA.
*
* Please mail bug reports to bug-lyskom@lysator.liu.se.
*/
/*
* stats.c -- Handle statistical information, such as load averages.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include
<assert.h>
#include
"timewrap.h"
#include
<string.h>
#include
<stdio.h>
#include
"stats.h"
#include
"log.h"
#include
"lyskomd.h"
#define FACT_00 (1)
/* 1 second */
#define FACT_0 (15)
/* 15 seconds */
#define FACT_1 ( 4 * FACT_0)
/* 1 minute */
#define FACT_2 ( 5 * FACT_1)
/* 5 minutes */
#define FACT_3 ( 3 * FACT_2)
/* 15 minutes */
#define N_FACTS 5
#define HISTORY_LENGTH (FACT_3)
/* Define this to debug the average counting code. This will slow
down the code a lot, so it is not recommended for production use. */
#undef DEBUG_STATS
struct
avg_status
{
struct
timeval
when
;
long
value
;
float
acc
;
float
avg_history
[
HISTORY_LENGTH
];
double
avenrun
[
N_FACTS
];
long
updates
[
N_FACTS
];
};
static
struct
avg_status
status
[
NUM_STAT
];
static
struct
avg_status
copy
[
NUM_STAT
];
static
const
int
factors
[]
=
{
FACT_00
,
FACT_0
,
FACT_1
,
FACT_2
,
FACT_3
,
};
static
int
ind
(
unsigned
long
sec
,
unsigned
int
offset
)
{
int
ret
=
(
sec
+
offset
)
%
HISTORY_LENGTH
;
assert
(
ret
>=
0
);
assert
(
ret
<
HISTORY_LENGTH
);
return
ret
;
}
#ifdef DEBUG_STATS
static
void
dump_stats
(
struct
avg_status
*
s
)
{
int
st
;
int
i
;
fprintf
(
stderr
,
"START DUMP
\n
"
);
for
(
st
=
0
;
st
<
NUM_STAT
;
st
++
)
{
fprintf
(
stderr
,
"stats for type %d: when=%ld:%ld value=%ld acc=%f
\n
"
,
st
,
(
long
)
s
[
st
].
when
.
tv_sec
,
(
long
)
s
[
st
].
when
.
tv_usec
,
s
[
st
].
value
,
s
[
st
].
acc
);
fprintf
(
stderr
,
" indices:"
);
fprintf
(
stderr
,
" ():0:%d"
,
ind
(
s
[
st
].
when
.
tv_sec
,
0
));
for
(
i
=
0
;
i
<
N_FACTS
;
i
++
)
fprintf
(
stderr
,
" %d:%d:%d"
,
i
,
factors
[
i
],
ind
(
s
[
st
].
when
.
tv_sec
,
-
factors
[
i
]));
fprintf
(
stderr
,
"
\n
avenrun:"
);
for
(
i
=
0
;
i
<
N_FACTS
;
i
++
)
fprintf
(
stderr
,
" %f"
,
s
[
st
].
avenrun
[
i
]);
fprintf
(
stderr
,
"
\n
updates:"
);
for
(
i
=
0
;
i
<
N_FACTS
;
i
++
)
fprintf
(
stderr
,
" %ld"
,
s
[
st
].
updates
[
i
]);
fprintf
(
stderr
,
"
\n
history:"
);
for
(
i
=
0
;
i
<
HISTORY_LENGTH
;
i
++
)
fprintf
(
stderr
,
" %f"
,
s
[
st
].
avg_history
[
i
]);
fprintf
(
stderr
,
"
\n
"
);
}
}
#endif
void
init_stats
(
void
)
{
int
t
;
int
i
;
struct
timeval
now
;
assert
(
sizeof
(
factors
)
/
sizeof
(
factors
[
0
])
==
N_FACTS
);
assert
(
factors
[
N_FACTS
-
1
]
==
HISTORY_LENGTH
);
gettimeofday
(
&
now
,
NULL
);
for
(
t
=
0
;
t
<
NUM_STAT
;
t
++
)
{
status
[
t
].
when
=
now
;
status
[
t
].
value
=
0
;
status
[
t
].
acc
=
0
.
0
;
for
(
i
=
0
;
i
<
HISTORY_LENGTH
;
i
++
)
status
[
t
].
avg_history
[
i
]
=
0
.
0
;
for
(
i
=
0
;
i
<
N_FACTS
;
i
++
)
{
status
[
t
].
avenrun
[
i
]
=
0
.
0
;
status
[
t
].
updates
[
i
]
=
0
;
}
}
}
static
void
update_history
(
struct
avg_status
*
s
,
time_t
end
,
float
value
)
{
int
i
;
for
(;
s
->
when
.
tv_sec
<
end
;
s
->
when
.
tv_sec
++
)
{
for
(
i
=
0
;
i
<
N_FACTS
;
i
++
)
s
->
avenrun
[
i
]
+=
(
value
-
s
->
avg_history
[
ind
(
s
->
when
.
tv_sec
,
-
factors
[
i
])])
/
(
double
)
factors
[
i
];
s
->
avg_history
[
ind
(
s
->
when
.
tv_sec
,
0
)]
=
value
;
}
}
void
update_stat
(
enum
stat_type
st
,
long
delta
)
{
struct
timeval
now
;
long
time_delta
;
int
i
;
struct
avg_status
*
s
=
&
status
[
st
];
assert
(
st
<
STAT_FIRST_EVENT
||
delta
>=
0
);
memcpy
(
copy
,
status
,
sizeof
(
status
));
gettimeofday
(
&
now
,
NULL
);
if
(
now
.
tv_sec
==
s
->
when
.
tv_sec
)
{
if
(
st
<
STAT_FIRST_EVENT
)
{
time_delta
=
now
.
tv_usec
-
s
->
when
.
tv_usec
;
if
(
time_delta
!=
0
)
s
->
acc
+=
(
float
)
s
->
value
/
time_delta
;
s
->
when
.
tv_usec
=
now
.
tv_usec
;
}
}
else
if
(
now
.
tv_sec
-
s
->
when
.
tv_sec
<=
HISTORY_LENGTH
)
{
if
(
st
<
STAT_FIRST_EVENT
)
{
time_delta
=
1000000
-
s
->
when
.
tv_usec
;
if
(
time_delta
!=
0
)
s
->
acc
+=
(
float
)
s
->
value
/
time_delta
;
}
else
s
->
acc
=
s
->
value
;
update_history
(
s
,
s
->
when
.
tv_sec
+
1
,
s
->
acc
);
if
(
st
>=
STAT_FIRST_EVENT
)
{
s
->
acc
=
0
;
s
->
value
=
0
;
}
update_history
(
s
,
now
.
tv_sec
,
s
->
value
);
assert
(
s
->
when
.
tv_sec
==
now
.
tv_sec
);
if
(
st
<
STAT_FIRST_EVENT
)
{
if
(
now
.
tv_usec
==
0
)
s
->
acc
=
0
;
else
s
->
acc
=
(
float
)
s
->
value
/
now
.
tv_usec
;
s
->
when
.
tv_usec
=
now
.
tv_usec
;
}
}
else
{
if
(
st
>=
STAT_FIRST_EVENT
)
{
s
->
acc
=
0
;
s
->
value
=
0
;
}
for
(
i
=
0
;
i
<
N_FACTS
;
i
++
)
s
->
avenrun
[
i
]
=
s
->
value
;
for
(
i
=
0
;
i
<
HISTORY_LENGTH
;
i
++
)
s
->
avg_history
[
i
]
=
s
->
value
;
if
(
st
<
STAT_FIRST_EVENT
)
{
if
(
now
.
tv_usec
==
0
)
s
->
acc
=
0
;
else
s
->
acc
=
(
float
)
s
->
value
/
now
.
tv_usec
;
}
s
->
when
=
now
;
}
s
->
value
+=
delta
;
for
(
i
=
0
;
i
<
N_FACTS
;
i
++
)
s
->
updates
[
i
]
++
;
if
(
s
->
value
<
0
)
{
kom_log
(
"update_stat(%d, %ld): current value became negative: %ld
\n
"
,
st
,
delta
,
s
->
value
);
s
->
value
=
0
;
}
#ifdef DEBUG_STATS
if
(
check_stat
(
"update_stats"
)
>
0
)
{
kom_log
(
"This was caused by an update of delta=%ld for type %d
\n
"
,
delta
,
st
);
kom_log
(
"Dump of before:
\n
"
);
dump_stats
(
copy
);
kom_log
(
"Dump of after:
\n
"
);
dump_stats
(
status
);
}
#endif
}
extern
int
check_stat
(
const
char
*
when
)
{
struct
avg_status
*
s
;
double
acc
;
double
err
;
float
val
;
int
st
;
int
f
;
int
i
;
int
changes
=
0
;
for
(
st
=
0
;
st
<
NUM_STAT
;
st
++
)
{
s
=
&
status
[
st
];
for
(
f
=
0
;
f
<
N_FACTS
;
f
++
)
{
acc
=
0
;
for
(
i
=
0
;
i
<
factors
[
f
];
i
++
)
{
val
=
s
->
avg_history
[
ind
(
s
->
when
.
tv_sec
,
-
i
-
1
)];
assert
(
val
>=
0
);
acc
+=
val
;
}
acc
/=
factors
[
f
];
err
=
acc
-
s
->
avenrun
[
f
];
if
(
err
<
0
)
err
=
-
err
;
if
((
acc
<
1e-6
&&
err
>
1e-5
)
||
(
acc
>=
1e-6
&&
err
/
acc
>
0
.
01
))
{
kom_log
(
"Accumulated rounding errors fixed (%s) after"
" %ld updates (type=%d, f=%d, factor=%d): %f => %f
\n
"
,
when
,
s
->
updates
[
f
],
st
,
f
,
factors
[
f
],
s
->
avenrun
[
f
],
acc
);
s
->
avenrun
[
f
]
=
acc
;
s
->
updates
[
f
]
=
0
;
changes
++
;
}
}
}
return
changes
;
}
src/server/stats.h
0 → 100644
View file @
1e0b323a
/*
* Copyright (C) 2003 Lysator Academic Computer Association.
*
* This file is part of the LysKOM server.
*
* LysKOM is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* LysKOM is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with LysKOM; see the file COPYING. If not, write to
* Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
* or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
* MA 02139, USA.
*
* Please mail bug reports to bug-lyskom@lysator.liu.se.
*/
/*
* stats.h -- Handle statistical information, such as load averages.
*/
enum
stat_type
{
/* Average values. */
STAT_RUN_QUEUE
,
#if 0
STAT_DNS_QUEUE,
STAT_IDENT_QUEUE,
#endif
/* Events. */
STAT_FIRST_EVENT
,
STAT_PROCESSED_CALLS
=
STAT_FIRST_EVENT
,
STAT_RUN_QUEUE_ENTER
,
STAT_RUN_QUEUE_LEAVE
,
NUM_STAT
};
extern
void
init_stats
(
void
);
extern
void
update_stat
(
enum
stat_type
st
,
long
delta
);
extern
int
check_stat
(
const
char
*
when
);
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment