绘制按天分组的 HTTP 状态代码
Plot HTTP Status Codes Grouped by Days
我有一个带时间戳的 HTTP 状态代码流:
2021-02-09T10:54:00 200 50
2021-02-09T10:57:00 200 35
2021-02-09T11:00:00 200 50
2021-02-09T11:03:00 500 150
2021-02-09T11:06:00 500 350
2021-02-09T11:09:00 500 450
2021-02-09T11:12:00 500 1000
2021-02-09T11:15:00 404 35
2021-02-09T11:18:00 404 50
2021-02-09T11:21:00 200 50
2021-02-09T11:24:00 200 35
2021-02-09T11:27:00 200 50
2021-02-09T11:30:00 200 50
我已经设法设置 gnuplot
来对日期进行分组:
set xdata time
set ydata time
set format y "%H:%M"
set timefmt "%Y-%m-%dT%H:%M:%S"
set xrange ["2021-02-08T00:00:00":"2021-02-14T23:59:59"]
plot 'availability.csv' using (timecolumn(1,"%Y-%m-%d")):(timecolumn(1,"%H-%M")):2…
我已经找到了很多示例,例如对一天求和(框/直方图)或标记每天的时间点(点)。但是 none 随着时间的推移符合我的可用性目标。
我的目标是每天将一个栏分到 15 分钟的区块。每个块应根据最大状态代码着色,例如HTTP.500=red,HTTP.404=yellow,HTTP.200=green(只有这 3 个,没有 teapot/redirect/spooky,颜色就像交通灯)。 Y 轴是一天中的小时,x 轴是一天。
- 我走的路对吗,
gnuplot
有可能吗?
using
子句是什么样的?
- 如何将 15 分钟间隔合并到第二列中?
- 如何给具体代码上色? (它不像从频率计算颜色的热图)
我将从以下内容开始。
timecolumn(1,"%H-%M")
不会从像 "2021-02-08T12:34:56"
这样的时间字符串中提取小时和分钟。据我所知,首先我们必须提取 12:34
部分,然后将其转换为小时和分钟:
strptime("%H:%M", strcol(1)[12:17])
时间戳在内部存储为秒,因此使用整数除法可以达到 15 分钟(= 900 秒)分箱:int(<seconds>)/900*900.0
像 plot "a.dat" using 1:(<expression>, value)
这样的 gnuplot 命令计算表达式并绘制值。这用于...
“手动”select bin 中的最大值。该脚本遍历 bin 中的所有点并记住最大值。请阅读help ternary
。我使用了两次三元运算符:一次用于检查 bin,一次用于检查最大值
颜色请阅读help set palette
这是完整的脚本:
set xdata time
set ydata time
set format y "%H:%M"
set timefmt "%Y-%m-%dT%H:%M:%S"
set xrange ["2021-02-08T00:00:00":"2021-02-14T23:59:59"]
set palette defined (200 "green", 400 "yellow", 500 "red")
unset colorbox
bin = 0
bin_before = 0
max_value = 0
plot 'availability.csv' using \
(timecolumn(1,"%Y-%m-%d")):\
(bin = (int(strptime("%H:%M", strcol(1)[12:17]))/900*900), bin):\
(y = , bin == bin_before ? (y>max_value ? max_value = y : max_value = max_value) \
: (max_value = y, bin_before = bin), max_value ) \
linecolor palette pt 5 ps 2 notitle
这是结果:
我认为我们还没有完成,应该添加一个图例,检查 splot
和 pm3d
的可能性可能会很有趣。
有趣的挑战。我的建议如下。这可能不是最简单的,但我会说结果看起来很合理。它使用绘图样式 with boxxyerror
(参见 help boxxyerror
)。
根据你的问题,我了解到你想要一个 15 分钟的 binning 并且只显示该时间间隔内最大状态的颜色。为什么不显示每个间隔的不同状态的直方图?例如:如果区间内有以下HTTP状态:2x 200、1x 404和2x 500。那么这个区间内的横条将被分割成40%的绿色、20%的黄色和40%的红色。
以下代码的基本作用:
- 创建一些随机测试数据(仅供说明)
- 使用
smooth freq
(检查 help smooth
)对数据进行装箱,并为 3 个不同的状态添加 1、2、3 秒的小偏移量。
- 做一些 table 重新排列
- 使用框的 x、y 位置创建最终 table,并对应于每个状态在分箱间隔内的相对贡献。
为了更好的理解:
数据块的示例数据$Data
:
2021-02-10T12:30:00 200 407
2021-02-10T12:33:00 200 922
2021-02-10T12:36:00 404 615
2021-02-10T12:39:00 200 689
2021-02-10T12:42:00 200 628
2021-02-10T12:45:00 500 10
2021-02-10T12:48:00 200 185
2021-02-10T12:51:00 200 2
2021-02-10T12:54:00 404 743
2021-02-10T12:57:00 200 618
数据块的示例数据$Histo3
:
1612960200 5 i
1612960201 4 i
1612960202 1 i
1612961100 5 i
1612961101 3 i
1612961102 1 i
1612961103 1 i
数据块的示例数据$Histo4
:
NaN 0 nan 12:30 0
2021-02-10 0 0.8 12:30 1
2021-02-10 0.8 1 12:30 2
NaN 0 nan 12:45 0
2021-02-10 0 0.6 12:45 1
2021-02-10 0.6 0.8 12:45 2
2021-02-10 0.8 1 12:45 3
代码当然可以优化。因此,将其视为一个起点...
代码:
### status overview as date/time dependent histograms
reset session
# general settings
myDateFmt = "%Y-%m-%d" # date only format
myTimeFmt = "%H:%M:%S" # time only format
myDateTimeFmt = myDateFmt."T".myTimeFmt # datetime format
SecPerDay = 24*3600 # seconds per day
myStatusList = "200 404 500" # possible states
myColorList = "0x00ff00 0xffff00 0xff0000" # green, yellow, red
# create some random test data
set print $Data
myTime = time(0) # now
myRandomStatus(x) = x<0.70 ? 1 : x<0.95 ? 2 : 3 # random status
myInterval = 3 # interval in minutes
do for [i=1:5000] {
myTime = myTime + myInterval*60
myStatus = word(myStatusList,myRandomStatus(rand(0))) # random status
myValue = int(rand(0)*1000) # random value 0-999
print sprintf("%s %s %g",strftime("%Y-%m-%dT%H:%M:00",myTime),myStatus,myValue)
}
set print
# functions
myStatusNo(col) = column(col)==200 ? 1 : column(col)==404 ? 2 : 3
myColor(i) = int(i) ? int(word(myColorList,int(i))) : 1
myDayTime(t) = tm_hour(t)*3600 + tm_min(t)*60 + tm_sec(t)
# binning
BinWidthSec = 900 # in seconds 900 sec = 15 min
BinTime(col) = floor(myDayTime(timecolumn(col,myDateTimeFmt))/BinWidthSec)*BinWidthSec
set table $Histo1
set format x "%.0f"
plot $Data u (timecolumn(1,myDateFmt)+BinTime(1)):(1) smooth freq
plot $Data u (timecolumn(1,myDateFmt)+BinTime(1)+myStatusNo(2)):(1) smooth freq
set table $Histo2
plot $Histo1 u (sprintf("%.0f",)):2 w table # remove empty lines etc.
set table $Histo3
set format x "%.0f"
plot $Histo2 u 1:2 smooth freq # sort the events by time
unset table
# create final table
myX(col1,col2) = int(column(col1))%4==0 ? (Sum=0.0, Total=column(col2),"NaN") : \
strftime(myDateFmt,column(col1))
myXRelStart(col1,col2) = Sum/Total
myXRelEnd(col1,col2) = int(column(col1))%4==0 ? NaN : (Sum=Sum+column(col2), Sum/Total)
BinTimeT(col) = strftime("%H:%M",column(col))
set table $Histo4
plot $Histo3 u (sprintf("% 10s % 5g % 5g % 7s % 3d", \
myX(1,2), myXRelStart(1,2), myXRelEnd(1,2), BinTimeT(1), tm_sec())) w table
unset table
# plot settings
set format x "%d.%m." timedate
set format y "%H:%M" timedate
set style fill transparent solid 0.5 noborder
set yrange [0:SecPerDay]
set tics out
set key out title "HTTP status"
plot $Histo4 u (timecolumn(1,myDateFmt)+(+)/2*SecPerDay) : \
(timecolumn(4,myTimeFmt)+BinWidthSec/2) : \
((-)/2*SecPerDay) : (BinWidthSec/2.):(myColor()) \
w boxxy lc rgb var notitle, \
for [i=1:3] keyentry w boxes lc rgb myColor(i) title word(myStatusList,i)
### end of code
结果:
我有一个带时间戳的 HTTP 状态代码流:
2021-02-09T10:54:00 200 50
2021-02-09T10:57:00 200 35
2021-02-09T11:00:00 200 50
2021-02-09T11:03:00 500 150
2021-02-09T11:06:00 500 350
2021-02-09T11:09:00 500 450
2021-02-09T11:12:00 500 1000
2021-02-09T11:15:00 404 35
2021-02-09T11:18:00 404 50
2021-02-09T11:21:00 200 50
2021-02-09T11:24:00 200 35
2021-02-09T11:27:00 200 50
2021-02-09T11:30:00 200 50
我已经设法设置 gnuplot
来对日期进行分组:
set xdata time
set ydata time
set format y "%H:%M"
set timefmt "%Y-%m-%dT%H:%M:%S"
set xrange ["2021-02-08T00:00:00":"2021-02-14T23:59:59"]
plot 'availability.csv' using (timecolumn(1,"%Y-%m-%d")):(timecolumn(1,"%H-%M")):2…
我已经找到了很多示例,例如对一天求和(框/直方图)或标记每天的时间点(点)。但是 none 随着时间的推移符合我的可用性目标。
我的目标是每天将一个栏分到 15 分钟的区块。每个块应根据最大状态代码着色,例如HTTP.500=red,HTTP.404=yellow,HTTP.200=green(只有这 3 个,没有 teapot/redirect/spooky,颜色就像交通灯)。 Y 轴是一天中的小时,x 轴是一天。
- 我走的路对吗,
gnuplot
有可能吗? using
子句是什么样的?- 如何将 15 分钟间隔合并到第二列中?
- 如何给具体代码上色? (它不像从频率计算颜色的热图)
我将从以下内容开始。
timecolumn(1,"%H-%M")
不会从像"2021-02-08T12:34:56"
这样的时间字符串中提取小时和分钟。据我所知,首先我们必须提取12:34
部分,然后将其转换为小时和分钟:strptime("%H:%M", strcol(1)[12:17])
时间戳在内部存储为秒,因此使用整数除法可以达到 15 分钟(= 900 秒)分箱:
int(<seconds>)/900*900.0
像
plot "a.dat" using 1:(<expression>, value)
这样的 gnuplot 命令计算表达式并绘制值。这用于...“手动”select bin 中的最大值。该脚本遍历 bin 中的所有点并记住最大值。请阅读
help ternary
。我使用了两次三元运算符:一次用于检查 bin,一次用于检查最大值颜色请阅读
help set palette
这是完整的脚本:
set xdata time
set ydata time
set format y "%H:%M"
set timefmt "%Y-%m-%dT%H:%M:%S"
set xrange ["2021-02-08T00:00:00":"2021-02-14T23:59:59"]
set palette defined (200 "green", 400 "yellow", 500 "red")
unset colorbox
bin = 0
bin_before = 0
max_value = 0
plot 'availability.csv' using \
(timecolumn(1,"%Y-%m-%d")):\
(bin = (int(strptime("%H:%M", strcol(1)[12:17]))/900*900), bin):\
(y = , bin == bin_before ? (y>max_value ? max_value = y : max_value = max_value) \
: (max_value = y, bin_before = bin), max_value ) \
linecolor palette pt 5 ps 2 notitle
这是结果:
我认为我们还没有完成,应该添加一个图例,检查 splot
和 pm3d
的可能性可能会很有趣。
有趣的挑战。我的建议如下。这可能不是最简单的,但我会说结果看起来很合理。它使用绘图样式 with boxxyerror
(参见 help boxxyerror
)。
根据你的问题,我了解到你想要一个 15 分钟的 binning 并且只显示该时间间隔内最大状态的颜色。为什么不显示每个间隔的不同状态的直方图?例如:如果区间内有以下HTTP状态:2x 200、1x 404和2x 500。那么这个区间内的横条将被分割成40%的绿色、20%的黄色和40%的红色。
以下代码的基本作用:
- 创建一些随机测试数据(仅供说明)
- 使用
smooth freq
(检查help smooth
)对数据进行装箱,并为 3 个不同的状态添加 1、2、3 秒的小偏移量。 - 做一些 table 重新排列
- 使用框的 x、y 位置创建最终 table,并对应于每个状态在分箱间隔内的相对贡献。
为了更好的理解:
数据块的示例数据$Data
:
2021-02-10T12:30:00 200 407
2021-02-10T12:33:00 200 922
2021-02-10T12:36:00 404 615
2021-02-10T12:39:00 200 689
2021-02-10T12:42:00 200 628
2021-02-10T12:45:00 500 10
2021-02-10T12:48:00 200 185
2021-02-10T12:51:00 200 2
2021-02-10T12:54:00 404 743
2021-02-10T12:57:00 200 618
数据块的示例数据$Histo3
:
1612960200 5 i
1612960201 4 i
1612960202 1 i
1612961100 5 i
1612961101 3 i
1612961102 1 i
1612961103 1 i
数据块的示例数据$Histo4
:
NaN 0 nan 12:30 0
2021-02-10 0 0.8 12:30 1
2021-02-10 0.8 1 12:30 2
NaN 0 nan 12:45 0
2021-02-10 0 0.6 12:45 1
2021-02-10 0.6 0.8 12:45 2
2021-02-10 0.8 1 12:45 3
代码当然可以优化。因此,将其视为一个起点...
代码:
### status overview as date/time dependent histograms
reset session
# general settings
myDateFmt = "%Y-%m-%d" # date only format
myTimeFmt = "%H:%M:%S" # time only format
myDateTimeFmt = myDateFmt."T".myTimeFmt # datetime format
SecPerDay = 24*3600 # seconds per day
myStatusList = "200 404 500" # possible states
myColorList = "0x00ff00 0xffff00 0xff0000" # green, yellow, red
# create some random test data
set print $Data
myTime = time(0) # now
myRandomStatus(x) = x<0.70 ? 1 : x<0.95 ? 2 : 3 # random status
myInterval = 3 # interval in minutes
do for [i=1:5000] {
myTime = myTime + myInterval*60
myStatus = word(myStatusList,myRandomStatus(rand(0))) # random status
myValue = int(rand(0)*1000) # random value 0-999
print sprintf("%s %s %g",strftime("%Y-%m-%dT%H:%M:00",myTime),myStatus,myValue)
}
set print
# functions
myStatusNo(col) = column(col)==200 ? 1 : column(col)==404 ? 2 : 3
myColor(i) = int(i) ? int(word(myColorList,int(i))) : 1
myDayTime(t) = tm_hour(t)*3600 + tm_min(t)*60 + tm_sec(t)
# binning
BinWidthSec = 900 # in seconds 900 sec = 15 min
BinTime(col) = floor(myDayTime(timecolumn(col,myDateTimeFmt))/BinWidthSec)*BinWidthSec
set table $Histo1
set format x "%.0f"
plot $Data u (timecolumn(1,myDateFmt)+BinTime(1)):(1) smooth freq
plot $Data u (timecolumn(1,myDateFmt)+BinTime(1)+myStatusNo(2)):(1) smooth freq
set table $Histo2
plot $Histo1 u (sprintf("%.0f",)):2 w table # remove empty lines etc.
set table $Histo3
set format x "%.0f"
plot $Histo2 u 1:2 smooth freq # sort the events by time
unset table
# create final table
myX(col1,col2) = int(column(col1))%4==0 ? (Sum=0.0, Total=column(col2),"NaN") : \
strftime(myDateFmt,column(col1))
myXRelStart(col1,col2) = Sum/Total
myXRelEnd(col1,col2) = int(column(col1))%4==0 ? NaN : (Sum=Sum+column(col2), Sum/Total)
BinTimeT(col) = strftime("%H:%M",column(col))
set table $Histo4
plot $Histo3 u (sprintf("% 10s % 5g % 5g % 7s % 3d", \
myX(1,2), myXRelStart(1,2), myXRelEnd(1,2), BinTimeT(1), tm_sec())) w table
unset table
# plot settings
set format x "%d.%m." timedate
set format y "%H:%M" timedate
set style fill transparent solid 0.5 noborder
set yrange [0:SecPerDay]
set tics out
set key out title "HTTP status"
plot $Histo4 u (timecolumn(1,myDateFmt)+(+)/2*SecPerDay) : \
(timecolumn(4,myTimeFmt)+BinWidthSec/2) : \
((-)/2*SecPerDay) : (BinWidthSec/2.):(myColor()) \
w boxxy lc rgb var notitle, \
for [i=1:3] keyentry w boxes lc rgb myColor(i) title word(myStatusList,i)
### end of code
结果: