程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Sqlite 中的压缩 apache 日志大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_616_0@如何解决sqlite 中的压缩 apache 日志? 开发过程中遇到sqlite 中的压缩 apache 日志的问题如何解决?下面主要结合日常开发的经验,给出你关于sqlite 中的压缩 apache 日志的解决方法建议,希望对你解决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@解决方法

JSON1 + 压缩 + 视图

  1. 编译 compress(它是使用较旧的 libsqlite3-dev 编译的先前版本,您可能需要安装 zlib1g-devsqlite 扩展。默认情况下,JSON1 几乎总是已经存在。

    gcc -g -fPIC -shared compress.c -o compress.so
    
  2. 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

这仅适用于只读(历史时期)数据库。 SquashFS provides plenty of compression options:

原始版本的 Squashfs 使用了 log_block 压缩,然 Linux 内核 2.6.34 添加了对 gzipLZMA 压缩的支持,但 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,请注明来意。