大佬教程收集整理的这篇文章主要介绍了Sqlite 中的压缩 apache 日志,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我希望能够使用 sql 语法以与工具 asql
类似的方式查询我的 Apache 日志。
我正在使用以下代码将 Apache 日志导入 sqlite:
import sqlite3,apache_log_parser # pip install apache_log_parser
conn = sqlite3.connect('logs.db')
cur = conn.cursor()
cur.execute("""create table IF NOT EXISTS logs (server TEXT,port IntegeR,ip TEXT,time TEXT,url TEXT,status IntegeR,bytes IntegeR,referer TEXT,useragent TEXT)""")
parser = apache_log_parser.make_parser("%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"")
with open("other_vhosts_access.log") as f:
for line in f:
d = parser(linE)
cur.execute("""INSERT INTO logs VALUES (:server_name,:server_port,:remote_host,:time_received_isoformat,:@R_674_10613@est_url,:status,:bytes_tx,:@R_674_10613@est_header_referer,:@R_674_10613@est_header_user_agent)""",d)
cur.close()
conn.commit()
conn.close()
它有效。然而,一个月的 other_vhosts_access.log
200 MB 文件会生成近 200 MB 的 sqlite DB 文件(没有压缩)。所以在我的情况下 1 年的日志:
通常占用 500 MB:2 * 200 MB(前 2 个月为纯文本)+ 10 * 10 MB(前 10 个月由 logrotate
压缩)
现在需要:2.4 GB:12 * 200 MB
问题:有没有办法让 logs.db
(自动?)压缩,但仍然能够使用 sqlite 运行只读 SELECT * FROM logs WHERE ...
查询?
我见过 sqlite ZIPVFS 但这不是开源的(而且对我的项目来说太贵了)。
@H_616_0@解决方法编译 compress
(它是使用较旧的 libsqlite3-dev
编译的先前版本,您可能需要安装 zlib1g-dev
)sqlite 扩展。默认情况下,JSON1
几乎总是已经存在。
gcc -g -fPIC -shared compress.c -o compress.so
Chunk 解析日志 Dict
s,比如 1024(所以它压缩得很好),在一个 list
,json.dumps
列表中并将它传递给 {{1} } 其中 INSERT
它。创建一个视图,在 sqlite 一侧执行相反的操作。
这是表格和视图。
compress
写入表格的一个例子是这样的。
import sqlite3
conn = sqlite3.connect('/path/to/db.sqlite')
conn.load_extension('/path/to/compress.so')
conn.execute('''
create table "log_block" (
"log_block_id" INTEGER PRIMARY KEY AUTOINCREMENT,"created_at" datetiR_866_11845@E NOT NULL DEFAULT CURRENT_TIMESTAMP,"block" BLOB NOT NULL
)
''')
conn.execute('''
create view log_record AS
SELECT
json_extract(value,'$.server') "server",json_extract(value,'$.port') "port",'$.ip') "ip",'$.time') "time",'$.url') "url",'$.status') "status",'$.bytes') "bytes",'$.referer') "referer",'$.useragent') "useragent"
FROM log_block,json_each(uncompress(log_block.block))
''')
然后像查询当前未压缩表一样查询视图。
import itertools
import json
sample = {
'server': 'foo.bar','port': '80','ip': '127.0.0.1','time': '2013-08-16T15:45:34','url': '/','status': '200','bytes': '42','referer': 'https://example.com/','useragent': 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.18)',}
def chunk(iterable,n):
return (
tuple(filter(bool,C))
for c in itertools.zip_longest(*[iter(iterablE)] * n)
)
log_records = itertools.repeat(sample,10_000)
for c in chunk(log_records,1024):
conn.execute(
'INSERT INTO log_block(block) VALUES(compress(?))',(json.dumps(C),)
)
conn.commit()
它有利于存档,但检索速度不会很快(尽管对于您的数据量来说仍然应该没问题)。根据您的查询,您可以按某些字段对日志记录进行分组,例如 conn.execute('SELECT * FROM log_record LIMIT 1').fetchone()
,而不是任意分块并将它们移动到 url
表的列。然后您可以轻松地将它们编入索引。
这仅适用于只读(历史时期)数据库。 SquashFS provides plenty of compression options:
原始版本的 Squashfs 使用了 log_block
压缩,虽然 Linux 内核 2.6.34 添加了对 gzip
和 LZMA
压缩的支持,但 Linux 内核 2.6.38 添加了对 {{1} } 压缩(由 xz 使用),Linux 内核 3.19 添加了对 LZO
压缩的支持,Linux 内核 4.14 添加了对 LZMA2
压缩的支持。
这是一个示例(LZ4
来自 Zstandard
包)。
@H_451_3@mksquashfs
以上是大佬教程为你收集整理的Sqlite 中的压缩 apache 日志全部内容,希望文章能够帮你解决Sqlite 中的压缩 apache 日志所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。