我有一个整数值的位掩码(实际上是一个'flagmask')(1,2,4,8,16等),适用于一个字段,我需要将其存储在一个(文本)日志文件中。我有效地存储的是像"x=296"这表明对于字段&;x&;,设置了标志256、32和8。
在搜索日志时,如何方便地搜索到这个文本字符串("x=nnn"),并从"nnn"是否设置了特定的标志?例如,我怎么能看到数字就知道旗子8已经设置好了呢?
我知道这是一个有点琐碎的问题,如果我们正在做'真'位掩码处理,但我以前没有见过这样问-日志搜索将只是做字符串匹配,所以它只看到一个值"296"并且没有办法将它转换为它的组成标志-我们只是使用基本的字符串搜索,可能有一些简单的SQL在那里。
你最好的选择是做完整的字符串正则表达式匹配。
对于第8位,这样做:
SELECT log_line
FROM log_table
WHERE log_line
RLIKE 'x=(128|129|130|131|132|133|134|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|150|151|152|153|154|155|156|157|158|159|160|161|162|163|164|165|166|167|168|169|170|171|172|173|174|175|176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191|192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207|208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223|224|225|226|227|228|229|230|231|232|233|234|235|236|237|238|239|240|241|242|243|244|245|246|247|248|249|250|251|252|253|254|255)[^0-9]'
或简化为:
RLIKE 'x=(12[89]|1[3-9][0-9]|2[0-4][0-9]|25[0-5])[^0-9]'
字符串x=
必须存在于日志中,后跟十进制数,且后面后跟非十进制数。
对于位2集,这样做:
SELECT log_line FROM log_table WHERE log_line RLIKE 'x=(2|3|6|7|10|11|14|15|18|19|22|23|26|27|30|31|34|35|38|39|42|43|46|47|50|51|54|55|58|59|62|63|66|67|70|71|74|75|78|79|82|83|86|87|90|91|94|95|98|99|102|103|106|107|110|111|114|115|118|119|122|123|126|127|130|131|134|135|138|139|142|143|146|147|150|151|154|155|158|159|162|163|166|167|170|171|174|175|178|179|182|183|186|187|190|191|194|195|198|199|202|203|206|207|210|211|214|215|218|219|222|223|226|227|230|231|234|235|238|239|242|243|246|247|250|251|254|255)[^0-9]'
我在一些实时数据上测试bit2:
SELECT count(log_line)
...
count(log_line) | 128 |
---|
很大程度上取决于你有多"容易";"简易sql"必须.
如果您可以使用字符串拆分来分隔"X"从"296",然后使用与值296是很容易的。
如果不能,那么,正如您所观察到的,296不会产生其第8位状态的痕迹。您需要检查所有有第8位设置的值,当然这意味着恰好是可用值的一半。. 您可以稍微压缩regexp:
248 249 250 251 252 253 254 255 =>24 [89] | 25 (0 - 5)264 265 266 267 268 269 270 271 =>26日(4 - 9日)| 27 [01]280 281 282 283 284 285 286 287 =>28(鹿)296 297 298 299 300 301 302 303 =>29 [6 - 9] | 30 [1 - 3]
…24[89]| 25(0 - 5)| 26(4 - 9日)| 27[01](鹿)| | 28 29 30[1 - 3][6 - 9]|…
,但我认为评估树不会改变太多,这种优化已经存在于大多数正则表达式引擎中。演出会很糟糕的。
如果可能的话,我会尝试重新制作日志(可能使用过滤器),将其重写为"X=000100101000b"或者至少"X=0128h"。后一个十六进制将允许您搜索第8位,查找"X=…[89A-F]h"。
我有几次不得不做这样的更改——它涉及准备一个管道过滤器来创建新日志(如果日志记录过程直接写入文件,情况会更复杂——最坏的情况是,您可能被迫永远不会在当前日志文件上运行搜索,或者在需要这样的搜索时轮换日志),然后在低负载期间缓慢地检索、解压缩、解析、重新压缩并存储回旧日志。这很长很无聊,但却是可行的。
对于数据库存储的日志,这要容易得多,您甚至可以避免对处理日志的过程进行任何更改—您可以为要转换的行添加一个标志,或者保留追赶转换的时间戳:
选择……从日志中创建>低水位命令:选择……从日志创建<</p>
将更新检索到的行,并使用检索到的最后一个创建值更新相应的水印。"lowWaterMark"跟踪日志记录过程。这样你就不能从当前瞬间搜索到低水印,低水印会"滞后"。落后(最终,只有几秒钟,除非负载很重)。
使用位操作符&检查值
中是否设置了特定标志function hasFlag(value, flag) {
return (value & flag) === flag;
}
const value = 296;
console.log(hasFlag(value, 256)); // true
console.log(hasFlag(value, 32)); // true
console.log(hasFlag(value, 8)); // true
console.log(hasFlag(value, 4)); // false