SLS新增单位转换函数——消除数据转换烦恼

日常烦恼

作为工程师,我们在日常工作中,经常会遇到数据单位或时间单位不一致的日志或者指标数据,很多公共软件也都是将指标或数据以方便阅读的单位形式进行输出和展示的。

这类数据虽然阅读方便,但是一旦需要进行汇总分析或者进行比较排序时,往往需要将数据的单位大小进行归一化,然后再进行后续处理,这个工作本身不难但却非常繁琐,常常让我们感觉到蹩手蹩脚,影响工作效率。


一个例子

例如,下面是一个具体的实例,左图是java gc原生日志,右图是经过数据切割后的指标数据。

SLS新增单位转换函数——消除数据转换烦恼

现在,我们需要分析每次垃圾回收后的jvm内存占比,计算公式:heap_used_after / heap_capacity_after,但是heap_used_after是M为单位,而heap_capacity_after是G为单位,为此,我们需要写出如下繁琐的SQL:

heap_used_after | select (cast(replace(heap_used_after, 'M') as double) * 1024 * 1024) / (cast(replace(heap_capacity_after, 'G') as double) * 1024 * 1024 * 1024)

事实上,事情可能还并非如此简单,heap_used_after的单位可能是M,可能是K,也可能是G,因此我们需要针对每种情况分别进行转换,于是,SQL变得更加冗长而繁琐:

heap_used_after |
select
  (
    CASE
      WHEN regexp_like(heap_used_after, '\d+\.?\d*B$') then cast(replace(heap_used_after, 'B') as double)
      WHEN regexp_like(heap_used_after, '\d+\.?\d*K$') then cast(replace(heap_used_after, 'K') as double) * 1024
      WHEN regexp_like(heap_used_after, '\d+\.?\d*M$') then cast(replace(heap_used_after, 'M') as double) * 1024 * 1024
      WHEN regexp_like(heap_used_after, '\d+\.?\d*G$') then cast(replace(heap_used_after, 'G') as double) * 1024 * 1024 * 1024
      ELSE 0.0
    END
  ) / (
    CASE
      WHEN regexp_like(heap_capacity_after, '\d+\.?\d*B$') then cast(replace(heap_capacity_after, 'B') as double)
      WHEN regexp_like(heap_capacity_after, '\d+\.?\d*K$') then cast(replace(heap_capacity_after, 'K') as double) * 1024
      WHEN regexp_like(heap_capacity_after, '\d+\.?\d*M$') then cast(replace(heap_capacity_after, 'M') as double) * 1024 * 1024
      WHEN regexp_like(heap_capacity_after, '\d+\.?\d*G$') then cast(replace(heap_capacity_after, 'G') as double) * 1024 * 1024 * 1024
      ELSE 1.0
    END
  )

没有人希望保留上面一大坨代码,只为了计算一个占比。


更多案例

在平时的数据分析工作中,我们还有很多这样的案例,比如:

由于数据单位不一,无法按大小排序...

SLS新增单位转换函数——消除数据转换烦恼

由于数据太大,想转换成方便阅读的大小...

SLS新增单位转换函数——消除数据转换烦恼

时间单位不一,无法进行汇总计算...

SLS新增单位转换函数——消除数据转换烦恼


现在,麻烦解决了

现在,SLS新增了单位转换函数,用来高效解决此类问题,专心为您排忧解难。

DataSize转换函数

针对上述示例,只需如下的简洁SQL即可:

heap_used_after |
select to_data_size_B(heap_used_after), to_data_size_B(heap_capacity_after)

不管heap_used_after的单位是B,是KB,是MB,还是GB,to_data_size_B()函数都可以统一转到以Byte为单位的大小。

您还可以使用以下函数,将数据对齐转换到对应的单位:

  • to_data_size_B,将任意单位的数据转换为以Byte为单位的大小
  • to_data_size_KB,将任意单位的数据转换为以KB为单位的大小
  • to_data_size_MB,将任意单位的数据转换为以MB为单位的大小
  • to_data_size_GB,将任意单位的数据转换为以GB为单位的大小
  • to_data_size_TB,将任意单位的数据转换为以TB为单位的大小
-- 将data_size转换为Byte单位
select '50128371B' as data_size, to_data_size_B('50128371B');
 data_size |    _col1
-----------+-------------
 50128371B | 5.0128371E7
 
-- 将data_size转换为KB单位
select '50128371B' as data_size, to_data_size_KB('50128371B');
 data_size |  _col1
-----------+----------
 50128371B | 48953.49
 
-- 将data_size转换为MB单位
select '50128371B' as data_size, to_data_size_MB('50128371B');
 data_size | _col1
-----------+-------
 50128371B | 47.81

-- 将data_size转换为GB单位
select '50128371B' as data_size, to_data_size_GB('50128371B');
 data_size | _col1
-----------+-------
 50128371B |  0.05

时间间隔转换函数

时间间隔(duration)同样也是非常常见的日志和指标数据,常用于表示系统执行一个请求的耗时,它的大小往往随请求大小、系统负载等因素而变化,具体ns、us、ms、s、m、h、d等不同的单位。

针对时间间隔数据,SLS提供了相应的转换函数如下:

  • to_nanoseconds(),将任意单位的时间间隔转换为以纳秒为单位的大小
  • to_microseconds(),将任意单位的时间间隔转换为以微秒为单位的大小
  • to_milliseconds(),将任意单位的时间间隔转换为以毫秒为单位的大小
  • to_seconds(),将任意单位的时间间隔转换为以秒为单位的大小
  • to_minutes(),将任意单位的时间间隔转换为以分钟为单位的大小
  • to_hours(),将任意单位的时间间隔转换为以小时为单位的大小
  • to_days(),将任意单位的时间间隔转换为以天为单位的大小
  • to_most_succinct_time_unit(),将任意单位的时间间隔转换为方便阅读的最靠近的极简单位的大小
-- 统一对齐到微秒
select time, to_microseconds(time);
 time  |    _col1
-------+-------------
 175ns |           0
 312us |         312
 18ms  |       18000
 32s   |    32000000
 1.2m  |    72000000
 0.56h |  2016000000
 0.2d  | 17280000000
 
-- 统一对齐到毫秒
select time, to_milliseconds(time);
 time  |  _col1
-------+----------
 175ns |        0
 312us |        0
 18ms  |       18
 32s   |    32000
 1.2m  |    72000
 0.56h |  2016000
 0.2d  | 17280000
 
-- 统一对齐到秒
select time, to_seconds(time);
 time  | _col1
-------+-------
 175ns |     0
 312us |     0
 18ms  |     0
 32s   |    32
 1.2m  |    72
 0.56h |  2016
 0.2d  | 17280
 
-- 转换为方便阅读的极简单位
select time, to_most_succinct_time_unit(time);
 time  |  _col1
-------+----------
 175ns | 175.00ns
 312us | 312.00us
 18ms  | 18.00ms
 32s   | 32.00s
 1.2m  | 1.20m
 0.56h | 33.60m
 0.2d  | 4.80h

此外,我们还专门提供了对时间间隔的解析函数:

  • parse_duration()
  • format_duration()
-- 对string类型的时间间隔进行解析,返回DAY-SECOND的表示形式
select time, parse_duration(time);
 time  |     _col1
-------+----------------
 175ns | 0 00:00:00.000
 312us | 0 00:00:00.000
 18ms  | 0 00:00:00.018
 32s   | 0 00:00:32.000
 1.2m  | 0 00:01:12.000
 0.56h | 0 00:33:36.000
 0.2d  | 0 04:48:00.000
 
-- 对double类型的秒级时间间隔进行格式化,返回可读的时间间隔字符串
select time, format_duration(time);
  time   |              _col1
---------+---------------------------------
    12.0 | 12 seconds
   134.0 | 2 minutes, 14 seconds
   235.0 | 3 minutes, 55 seconds
    12.4 | 12 seconds
   283.1 | 4 minutes, 43 seconds
 22415.4 | 6 hours, 13 minutes, 35 seconds


小结

在数据处理和分析过程中,数据单位或时间单位不一致,往往给分析工作带来困扰,降低了工作效率,使分析SQL变得复杂而臃肿。

SLS充分考虑到“这一点小麻烦”,为用户贴心地提供了相关的单位转换函数,可以在不同单位之间轻松地进行转换、统一单位、格式化为可读文本。

从此,您的数据转换烦恼将被消除。


进一步参考

SLS单位换算函数官方详细参考文档:SLS新增单位转换函数——消除数据转换烦恼点击进入

欢迎钉钉扫群加入阿里云-日志服务(SLS)技术交流, 获得第一手资料与支持

SLS新增单位转换函数——消除数据转换烦恼

更多SLS的系列直播与培训视频会同步到B站,SLS的相关文章会同步到微信公众号与知乎敬请关注

SLS新增单位转换函数——消除数据转换烦恼


上一篇:网络技术信息化对物流管理的影响


下一篇:puppet 配置 3.1 管理 sysct.conf