使用 lout 绘图
大多数文档工具也可以制作图表。本文将向您展示如何使用 lout,一种文档布局语言,来创建图表。最后,我们将有一个脚本来创建一个系统活动历史图表。
首先,lout 是一个文档布局程序,可以生成 PostScript。它由澳大利亚悉尼大学巴塞尔计算机科学系的 Jeffrey Kingston 编写。它在 Red Hat 发行版(如 Caldera)和许多 Linux ftp 站点上可用。此外,原始源代码可在 ftp.cs.su.oz.au 的 “jeff” 目录下找到。
在许多方面,lout 是 PostScript 的预处理器,因为许多 lout 语句会转换为 PostScript 指令。在其他方面,lout 是一种用于编写结构化文档的语言——我们使用 lout 命令描述列表、节、章、书籍和报告,而我们的文本则成为这些命令的参数。在本文中,我们将重点关注 lout 图形包中的命令,并忽略其用于文档的其他功能。
一般来说,lout 命令以商业 at 符号 @ 开头。命令的参数出现在其右侧,用花括号括起来,选项设置可以出现在命令及其参数之间
@Command options { argument }
通常,参数也可以包含 lout 命令,因此我们将得到嵌套的参数组,其花括号有助于整理一切。
让我们直接开始,看看一个简单的用于图表的 lout 文档
@SysInclude {graph} @SysInclude {doc} @Doc @Text @Begin @Graph { @Data pairs {solid} { 1 1 2 10 3 5 } } @End @Text
将此内容放入名为 graph.l 的文件中,并像这样运行 lout
lout -s -o ps graph.l
lout 读取输入文件,并生成 PostScript,将其写入输出文件,此处称为 ps。-s 告诉 lout 我们有一个独立文档,并且我们不希望它创建交叉引用文件。
当您使用 Ghostview 查看生成的 ps 文件(或将其打印到打印机)时,您会在页面顶部看到一个漂亮的小图表。lout 已自动生成一个框,计算出一些适当的比例,绘制了线条并显示了图表。lout 中的图形包有许多选项可以修改此图表的特性;我们稍后将看到其中的一些。
现在,重要的部分是 @Graph 命令
@Graph { @Data options { data-values } }
这告诉 lout 从其参数列表中的数据集创建一个图表。我们给 @Data 命令选项 “pairs {solid}”,这告诉 lout 数据集具有 x-y 坐标值对,并且我们希望数据点用实线连接。
至于示例的其余部分,@SysInclude 命令告诉 lout 我们将在文档中使用哪些包。@Doc 命令表示文档的主体在后面,它由 @Text @Begin 和 @End @Text 语句分隔。而这几乎是 lout 最难的部分了。
假设我们想制作一个系统活动图表。我们将需要三条曲线,分别用于用户、系统和空闲百分比。用户百分比曲线将是一条实线,带有填充圆圈以指示每个数据点。系统和空闲百分比曲线在每个数据点上都不会有符号,但系统百分比曲线将是虚线,而空闲百分比曲线将是点线。
从数据集到图表本身,我们希望图表以横向方向填充页面。顶部将有一个标题,图表下方有一个简短的描述,左侧有一个 y 轴标签。我们不希望使用图例框来识别曲线,而是希望在图表上每条曲线的最后一个点的右侧添加适当的标签。
这就是我们想要的。我们如何实现它?我们将使用 awk 作为 vmstat 和 lout 之间的接口。整体流程如下所示
vmstat | awk | lout
vmstat 生成一段时间内系统活动的数字,并将它们传递给 awk。awk 的作用是获取这些数字,收集它需要的数字,并为 lout 生成 @Graph 和 @Data 语句。最后,lout 获取其文档并将其转换为 PostScript。我们可以获取 PostScript 输出并查看、打印或将其嵌入到其他地方。如果系统一直运行,我们甚至可以使用 crontab 条目来自动打印每日活动报告,在每天结束时。
完整的脚本如清单 1 所示。让我们一起逐步浏览它。echo 命令发送 lout 设置代码;我们包含 graph 和 doc 包,设置文档的默认字体,并关闭页眉以避免获取页码。
在 @Text @Begin 语句之后,我们显示旋转后的图表,或者,如在 lout 中表达的那样
@Display 90d @Rotate @Graph { ... }
这里的 @Rotate 命令接受两个参数:左侧是要旋转的度数,右侧是要旋转的 lout 对象。在本例中,我们旋转的对象是整个图表。
@Graph 语句后跟几个图形选项。我们设置了图形大小,并设置了一些标题。我们使用 abovecaption { title text } 在图表上方添加标题。类似地,我们在图表下方添加注释,并在图表左侧添加 y 轴标签。请注意,我们旋转了 leftcaption,使其与图表的 y 轴平行。在标题之后,我们指定 x 轴上的刻度线。默认情况下,lout 仅每隔一分钟生成刻度线。我们可以使用 xticks 和 yticks 选项指定我们想要刻度线的位置以及每个刻度线的标签。在本例中,y 轴刻度线很好,但我们希望水平轴上每分钟都有一个刻度线和标签。最后两个图形选项告诉 lout 不要在图形曲线和图形轴之间留任何空白空间。这样,图表框的底线就成为图表的 0% 线。
现在所有设置都已完成,我们可以开始收集数据了。我们调用 vmstat,并告诉它我们想要每隔 10 秒采集 60 个样本,以收集 10 分钟内的数据。我们将这些测量值发送给 awk。
在 awk 脚本内部,我们将用户、系统和空闲百分比收集在单独的数组中,注意跳过标题行。当 vmstat 退出时,我们将使用这些保存的值为 lout 生成数据集。
在 awk 脚本的 END 例程内部,我们首先生成 lout 代码,将曲线标识符放在图表的右侧。在代码中,这些出现在 @Graph 命令的 objects { ... } 选项中。这是一个强大的功能,允许我们将几乎任何东西放在图表上的任何位置。在写入对象之后,我们可以生成数据集。一个 awk 函数为我们生成 lout 语句——我们将数组名称、点样式和线样式传递给名为 gen_data 的例程。它负责为 lout 生成格式良好的数据集。
最后,awk 脚本通过用 @End @Text 声明文本的结尾来完成 lout 文档。
echo 和 awk 的组合输出通过管道传递到 lout,lout 将系统活动图表的 PostScript 发送到其标准输出。此脚本可以作为许多其他图表的基础
我们可以将选项传递给 vmstat,以更好地控制采样间隔和持续时间。
我们可以不旋转图表来占据整个页面,而是将其保留在纵向对齐的页面上,并在其下方放置其他图表(例如,用于交换空间、可用内存和缓冲区内存)。
我们可以指示 awk 脚本通过在单独的数据集中更改线样式和点样式来突出显示严重的系统状况,当数据值变得太高或太低时。
我们可以为图表自动生成注释,显示系统百分比超过某个阈值时的时间和百分比值。
对于任何其他数据,原理都是相同的。需要磁盘使用情况图表吗?通过接口脚本运行 du 并生成一些 lout 代码,以图形方式显示系统上的磁盘占用大户。稍微修改脚本即可获得单个用户的目录使用情况图表。
我希望这篇简短的介绍已经激起了您对 lout 图形功能的兴趣。有关 lout 的更多信息,请参阅随附的出色用户手册和参考手册。它们涵盖了您使用 lout 所需了解的一切。
Mike Hall 是 BALR 公司的资深顾问,可以通过 mghall@balr.com 联系到他。