为什么我开发了 Db4E

最初尝试 Monero 挖矿和自托管基础设施时,我和其他人一样:下载 Monero、P2Pool、XMRig 软件,研究配置文件,编写自己的启动脚本,建立系统服务定义,终于让挖矿跑了起来。

但我很快发现,每个服务都有自己的配置格式、安装细节和生命周期管理需求。


没有分析工具

我盯着日志和 Monero 钱包,果然没多久就收到了第一笔收益。随着时间推移,收益持续到账,但我很难看出趋势,更不用说预测未来收入了。我对 XMRig 做的调整到底有没有效果?

让我几乎立刻注意到的是缺乏分析工具。我只能导出 Monero 钱包交易,导入电子表格,再画图。这种过程痛苦、临时拼凑,而且最糟糕的是每次都得手动重复。

任何程序员都会立刻发现:这是一个绝佳的自动化机会。


数据来源

Monero 钱包是一款高度注重安全的软件。我找不到方便的程序化交易记录访问方式,但我能够在 P2Pool 日志里看到交易,还有其他很有价值的信息。我意识到这是一座数据宝库。与其访问钱包,不如分析 P2Pool 日志,了解我的小型矿场随时间变化的表现。


持久化数据存储

于是我开始动手。这就是 Db4E 的起点。

我搭建持久化数据存储,先用 SQLite,再改用 ZODB,最终选择 MongoDB。我写了一个日志监控程序,观察 P2Pool 日志中的交易事件;顺便还收集了矿机、小型侧链和主链的发现份额、发现区块以及算力数据。反正能做到,为什么不呢?


数据分析:第一阶段

接着,我用 Urwid 写了一个仪表盘,每分钟查询一次 MongoDB。并不容易,Urwid 真是一头猛兽。2012 年它还很时髦,但在 2024 年使用它,实在让人头疼。我还是坚持下来了。

折腾了几个月后,我终于有了基础仪表盘。虽然还没图表,却能看到最近的 XMR 收款和发现的份额。总算迈出了第一步。


运维监控

我继续加入矿机、侧链和主链的算力数据,并为矿机数据加上时间戳,以便检测矿机是否掉线。系统开始有模有样,但仍然很脆弱,难以扩展。没有控制按钮,只是每分钟更新一次。不过至少我一眼就能看出一切正常。


数据分析:第二阶段

我还是没有绘图功能。仍然需要手动导出钱包交易,不过现在有脚本可以把导出内容整理成方便电子表格绘图的 CSV。依然很麻烦。

我考虑过 Tk/Tcl、GTK、Qt,但都没有使用经验。说实话,每一种方案都意味着陡峭的学习曲线、完整的桌面环境,以及一长串运行条件。对于我的需求,这似乎太复杂了。

然后我想:“用 Web 怎么样?”

浏览器就可以充当 GUI。GitHub Pages 提供免费托管,平台有了。经过研究,我选择 JavaScript + ApexCharts。我编写程序从 MongoDB 提取数据,生成 CSV 和 Markdown 文件,再通过 git 推送到 GitHub Pages。

我终于有图表了,可以看到每日收益和累计收益随时间变化的曲线。


自然而然出现的需求

我坐下来欣赏自己的成果,一切都很好。我搭建了一条管道:

P2Pool → Mongo → CSV → GitHub Pages → ApexCharts + Markdown。

它很复杂,跨越了不少技术,但确实能工作。

后来有一天,我浏览 Reddit 的 r/MoneroMining 时,随手截了几张图并发了一篇帖子。结果反响大得惊人。

帖子收获了一百多个赞。到写作时,已经有 27,000 次浏览。评论不断涌来:

“这是什么 GUI?看起来不错。” “很不错,我也许会试试。” “这款 GUI 叫什么名字?” “挺酷的。”

那一刻改变了一切。


部署工具

其实很合理,毕竟挖矿的人都会面临类似挑战。

但 Db4E 还没有被打包发布,它只是个业余项目。别人虽然可以克隆我的 GitHub 仓库,却还需要配置 Monero 区块链守护进程、P2Pool、XMRig,以及 Db4E 本身,才能复现我的环境。这可不简单。

如果我想分享成果,就需要创建一个部署工具。

于是我重新坐回键盘前。

我放弃 Urwid,因为它实在太难用,改用 Textual。Textual 是面向 Python 的快速应用开发框架,用来创建终端用户界面(TUI)。

如今,我已经建立了清晰的架构和功能完整的首次安装流程。最困难的部分已经完成。


接下来做什么

我提高了开发标准:正式发布版本,采用严格的 Git 分支和提交策略,并编写测试套件。

今天我要开发远程 Monero 守护进程部署。困难的工作已经完成,我预计当天就能做完。之后是本地 Monero 部署、P2Pool(本地与远程),以及 XMRig。这就构成完整的部署栈。

随着我对 Textual 的了解越来越深,我决定放弃 GitHub Pages + ApexCharts 历史趋势方案。它太公开了,会暴露挖矿活动,有点像向全世界广播你的 Bitcoin 钱包。取而代之,我会使用 plotext,直接在终端绘制漂亮的图表。

没错,所有东西都在终端里。

先别急着下判断,看看 Textual 网站,尤其是 Dolphie,再看看这个绘制天气数据的 plotext 示例应用。

我提到过运行健康状态吗?为什么不加上呢!

我还会加入健康检查,让你知道 monerod、P2Pool 或矿机何时掉线。还有类似这样的告警:

“过去一周,你的矿机算力下降了 20%。”

这也在计划之中。


为什么重要?

因为管理自己的基础设施,不应该要求你拥有 Linux 内部原理的博士学位、十几个临时脚本以及三个一直开着的终端。Db4E 让你有信心地运行服务,只需点击几下就能控制它们。


链接

👀 在 GitHub 上查看

📦 从 PyPI 安装

📬 有问题或反馈?欢迎提交 issue 或给我留言,我很乐意听听你的想法。

2026

Git Automation

Some of you may have read my Git Battles post, where I talked about how I developed and a documented a Git workflow.

My blog in Simplified Chinese

I recently built MyCount to track website visitors to my projects. I found that that over 40% of my visitors were from China, and that 35% of those used a Ch...

MyCount: Website Analytics & Marketing

I have a future project in mind which will require a Dynamic DNS service. I created BMDynIP for that purpose. After building the service, I wanted a simple a...

Animating Ax3l Playing Snake

I’ve been tinkering with various incarnations of Patrick Loeber’s Train an AI to Play Snake tutorial for a while now. It’s my relaxing goto project that’s fu...

Dynamic DNS Service

This project started as a cron job and a flatfile and -honestly- that would work perfectly well for a small home setup. Say, two or three machines. I’m curre...

Local GeoIP Database

The Bear & Moose GeoIP Project provides an easy-to-use GeoIP service for your applications and for interactive lookups.

An LLM to organize my Movies

Our first TV was a small black-and-white thing where, on rare occasions, we’d watch Animal Kingdom. Then Beta and VHS came along, and you could watch them at...

From Prototype to Product (4/4)

Fr3d worked: It could talk to the Snake Lab, propose changes to the RNN configuration, run experiments, look at the results, and try again. It proved the ide...

Prompt Engineering 101 (3/4)

The Snake Lab had become a proper server, with a ZeroMQ API, configuration validation, a database, and a way to run experiments independently of the client. ...

The Evolution of Snake Lab (2/4)

In my last post, I setup a locally hosted LLM running on an old HP Z440 and wrote a crude little conversation loop. I generated random numbers, fed them to t...

Local LLM Writes Haikus (1/4)

This is part one of a four part blog series. In this post, I download, install and setup some software to prompt a local LLM to write haikus…

From Seed to Signal: AI FX

In the first post, AI FX was still mostly a seed: a repo, a PyPI package, and an idea about using automated FOREX tooling as a learning lab. Since then, the ...

Simulating the Power Grid

A potential client pointed me to Empowering the Energy Transition Through Fast and Flexible Network Simulation. The article describes an Open Source project,...

Delphi in a Day

I have a prospective client who runs a small group of technology businesses, at least one of which integrates with clients using the Delphi programming lan...

A Small Experiment: AI FX

I’ve spent some time around trading systemsL At Merrill Lynch, I supported the Order Audit Trail System (OATS), a compliance system required by NASDAQ. Its p...

Back to top ↑

2025

My Art on Etsy

I setup an Etsy Storefront to sell high quality, museum grade prints of some of my artwork.

Python systemctl Wrapper

I’ve been working on Db4E, my Monero deployment, operations and analytics platform. It uses Linux systemd to spin up manage Monero, P2Pool and XMRig instance...

AI Snake Lab

AI Snake Lab is an interactive reinforcement learning sandbox for experimenting with AI agents in a classic Snake Game environment — featuring a live Textual...

The Power of Pictures

You know that saying, “A picture is worth a thousand words.”? In programming, I’d argue it can be worth a thousand lines of code…

Caring About Constants

This post is about using constants in your code. Why it matters, what the benefits are and how you can do it well. I’m sad to say, I learned this the hard wa...

Why I Built Db4E

When I first started experimenting with Monero mining and self-hosted infrastructure, I did what everyone else does: I downloaded the Monero software, the P2...

Releasing with Git

Let me be honest: Git has punched me in the face more times than I can count. Every time I think I’ve got a smooth release flow down, Git yells, “Not so fast...

Documentation Matters

I was burned by opaque documentation: I’ve been building a modern terminal UI in Python using the excellent Textual framework. It’s sharp, fast, and honestly...

Textual Replaces ApexCharts

The original reporting system was a set of static dashboards built using GitHub Pages, JavaScript, and ApexCharts. It pulled data from my mining setup — via ...

Pivot to Textual

I’ve been deep in the trenches with my Db4E project — pulling together Monero mining infrastructure, MongoDB integration, and a bunch of orchestration magic....

Released Db4E SystemD

I recently published a small Python module to PyPI and GitHub: db4e-systemd, a lightweight wrapper around systemctl that lets you control services (start, st...

NIKU Farms

I received my order from NIKU Farms, YAY! It’s a meat delivery that my sister, Corinna Ghaznavi, gifted me this Christmas. Every two months I receive this am...

The Main Website

As part of my goal to be more visible in the world, I setup this domain i.e. https://osoyalce.com. I use it to publish information about the projects I’m wor...

Reviving the Blog

It’s been a while since I started and then abandoned this blog. My last post was in June of 2024!!

Changing the Blog Site’s Layout

I decided that I didn’t like the way that the main blog page looks. I am using GitHub to host the website and am using a fork of the jekyll/minima theme. My ...

Back to top ↑

2024

Aquaponics Update #1

It’s in the construction phase. I need to complete the water circulation process. I bought a fiber glass kit for this (and also to fix my kitchen sink!).

What I’m working on

The XMR Mining Farm complete with this eye-popping chart The Bear and Moose Knowledge Base My resume MyZODB - A Place to Store Everything

Back to top ↑