Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: I built this Postgres logger (rocketgraph.io)
94 points by kvaranasi_ on Aug 24, 2023 | hide | past | favorite | 45 comments
Hey HN,

Some of you were really interested in Postgres logging with pgAudit in my previous post here: https://news.ycombinator.com/item?id=37082827

So I built this logger: https://rocketgraph.io/logger-demo

using pgAudit to show you what can be done with Postgres auditing. It offers some powerful features like "get me all the CREATE queries that ran in the past hour". These are generated by AWS RDS Instance running on my Rocketgraph account. Then they are forwarded to Cloudwatch for complex querying. In the future we can connect these logs to slack so you can get slack alerts when a developer accidentally DROPs a table.

If you like my work, please check it out here: https://github.com/RocketsGraphQL/rgraph

And if you want this logging on your own Postgres instance. Use https://rocketgraph.io/ And setup a project. pgAudit is automatically installed.




pgAudit is pretty cool, but it's a bit of a hassle for us currently because it keeps logging SELECT FOR UPDATE's even though SELECT is not allowed for the auditor, so if you implement stuff like simple queues with continuous polling it fills up the audit log with junk pretty fast. I opened a PR though so hopefully it gets fixed at some point.


Interesting. I did not know that. I have to dig into the source code then. Do you know any alternate logging tools that don't have this issue?


I think pgAudit it still the best and it's not a major issue. You can try my PR that fixes this issue https://github.com/pgaudit/pgaudit/pull/219 it should work and it should handle the other types of SELECT's that need update permissions but are not actually updating anything https://pglocks.org/?pglock=RowShareLock


Ok, looking into it.


FYI, be careful, see my other comments in reply but I think this is working correctly, and due to the fact that a `SELECT ... FOR UPDATE` is a write.


Yes, I have been reading the conversation. That was so much to learn. I did not know that `SELECT ... FOR UPDATE` is "sort of" a write. I googled and found out this SO link: https://stackoverflow.com/questions/18879584/postgres-select...

that corroborates what you have said.


This sounds like a desirable feature. SELECT FOR UPDATE results in a write where SELECT does not, and distinguishing between reads and writes is definitely something I'd want to be able to do here. Unless I've misunderstood the problem – I'm not sure I fully understand your PR.

Perhaps being able to exclude those as a separate category would be good?


What does a write in this context mean? I still need to execute the actual update clause to change the relevant data.

EDIT: Since you control object auditing by granting/revoking permissions to the relevant relations I don't think it's possible to have another category there since Postgres itself doesn't differentiate between UPDATE and SELECT FOR UPDATE on permission level


It means that the `FOR UPDATE` part in `SELECT ... FOR UPDATE` causes a disk write, because it locks that row. It bumps the MVCC metadata, the transaction ID on the tuple I think(?) in order to prevent other transactions from modifying it. While the data hasn't actually changed, the availability of that data has changed, so I think it's reasonable to consider that a write from the database perspective.

Although FWIW, I do completely understand your use-case of trying to quieten down logs for a queue!


Make sense. I guess it could also be a flag for the audit module where you can toggle if SELECT permission for auditing includes the SELECT clauses that need RowShareLock as well or not.


Yes! I don't think that should be a default because I think it's "safer" and more correct to consider locks writes, but having it available for pragmatic use-cases like this would be nice.


This looks great:)

> Use https://rocketgraph.io/ And setup a project.

What will the price and terms be?


1 week free trail. And for HN users I can give more time for the free trail. It'll be $50/mo. But it is worth a lot more.

But hey, you can sign up and create a project without your credit card. Once free trail ends, you can pay with stripe. Let me know how you like it.


This is just a front-end to CloudWatch Log Insights, right?


Sort of. I created this page to just show what can be done with pgAudit. But what I do at Rocketgraph is more. I provide Authentication, Postgres and GraphQl console. Postgres logger is an extension for demo purposes. In the future I plan to add slack alerts when a developer DROP's a database accidentally. And much more. Configuring AWS RDS is a pain.

I wrote about it here: https://blog.rocketgraph.io/posts/install-pgaudit

That's why I automated the process. Now every project comes with Postgres and pgAudit configured, Authentication, GraphQL and front-end SDKs right out of the box so it will be easier to develop web applications.


> In the future we can connect these logs to slack so you can get slack alerts when a developer accidentally DROPs a table.

What can you do about getting me a slack notice BEFORE a developer accidentally drops a table? ;)


Triboulet: "A noble has threatened to hang me!"

The Monarch: "Don't worry! If he hangs you I'll have him beheaded fifteen minutes later."

Triboulet: "Well, would it be possible to behead him 15 minutes before?


Hahahah. I literally Googled who Triboulet was.


Haha, exactly, but if you have developers who can drop production tables without the org knowing in advance and reviewing the change, you already have a big problem.

All our db operations like this go through our regular code review process for the db maintainers team, and instead of dropping tables, we just rename them with a prefix "to_be_dropped" as a scream test, then actually drop them a month later or so.

Recovery is much simpler for renaming than dropping.


This is a nice idea to check if any dependencies are there on the table.


Haha, yeah, it's a hack we figured out the hard way, but it is super simple and effective.


If you want to find the developer who will drop your table by accident, ask your devs to raise their hands if they ever dropped a table by accident. Those that don’t raise their hand are the ones you watch carefully.


Aye. A similar rite of passage: Any admin who hasn't nuked a server yet isn't working for long yet, or at their effective limit and is too careful.

We all have a few of these. My first one was a jenkins node with a "mv $WORKSPACE/ $WORKSPACE/bin" and no "set -u" :) Or accidentially wiping all SSH keys from a server due to a typo in the config management. That was fun.

But it's a good test for the mistake culture of the team and the resilience of their infrastructure. We had juniors nuke systems and no one but us and the monitoring noticed besides maybe a short hickup during a leader failover. That's pretty cool - and also a good horror story in a few words: "When you start ansible, and 3 minutes later on-call says 'Hi.' on slack".


Nope... but did check in the prod settings for the "local" config while working on a production bug close to the end of my contract. A couple weeks later another dev had dropped a production table as he'd used the local/dev connection string. Fortunately, every service request was logged and re-playable... so the DB was restored from backup, and every service request re-ran in order. Lost about a day of productivity for everyone using the app/service.

As to the config, this at least was pretty common for Web.*.config files in the .Net space in the mid 00s. I was never a fan of it, and even with the newer options in the space, prefer simpler environment variables these days.


"BEFORE a developer accidentally drops a table?"

Ideally, you don't want developer(s) to have access to destruct data especially things like DROP. Now, a lot of small businesses may not have the resource to have separate DBAs etc but the rule still applies.

This is more a control problem than a code problem. Having said that, you could write triggers to stop DELETE or DROPs from happening if you cannot control the access.


I've made it a personal rule for a while now, that I generally won't touch production once it is "online" ... I'll work initial setup, but after that, I'm happy to be on a screen sharing session walking someone else through what to do, so I don't have access and cannot touch it directly. Usually in favor of a CI/CD pipeline that will do regular releases. This at least lowers risk, but doesn't strictly prevent a DROP in a db/migration script.

All the same, I don't touch prod servers, and especially don't touch client prod servers.


Interesting idea to use Triggers.


Hey wait, you have a point though. We can put our custom locks onto tables that doesn't let anyone delete a particular table. Let me think over it. Saving this comment for later. Thanks for the idea man.


Uhm, why would you not use PG permissions for that? That's what they are for.


I am assuming that the developer has necessary permissions. If he/she accidentally deletes the table, then that's a problem.


That means that the process is wrong. it sounds like they are doing day to day work with credentials that can drop tables, which is dangerous and should probably be done through code-reviewed migration tooling.


Ok, yes this makes sense.


Of course I could be wrong. Please share with me your thoughts.


People using triggers for this just don't understand proper security - its a little harder but having your deployment process have the ability to drop tables and having your general user having read only query access (or insert powers on your own schema which nobody else can read) is stuff DBAs figured out in 90s and we keep forgetting.


What's a good place to start learning about these patterns ?


Well, it depends on your database, but honestly the knowledge was handed down to me by database enthusiasts of the times before.

I was studying SQL Server at the time, so Kendra Little, Brent Ozar, that whole crew were a good starting point.

Once you learn the basics of the DCL for your database, a lot of the stuff just becomes a natural extension, and almost always you're just talking about the official documentation.

Usually you have a server and a database level identity, and manipulating those usually break out the connection vs object level permissions.

Once you understand the maps of those and grouping users, you can do stuff like detect a user did a bad thing and add them to a group of users who are default denied from the database, insert a row in a table, and roll back their changes. A logon trigger that does rude things to people's sessions, or certainty that your developers can view some parts of some data without exposing your secrets.


Haha, exactly, but if you have developers who can drop production tables without the org knowing in advance and reviewing the change, you already have a big problem.


Well, I guess you could use https://www.postgresql.org/docs/16/sql-createeventtrigger.ht... to trigger on sql_drop

Maybe it could send a Slack message which you (some someone else) would need to react with (I think this site malforms that white checkmark unicode character though..) before it continues, or times out after a while with an error!


This is great. I plan on providing Postgres trigger templates that developers can easily load on Rocketgraph.


Postgres is one of the most amazing inventions that exit truly.


Like others have said, this is a control problem in prod (not using migrations in code and renaming instead of dropping). Anyways, as an fun exercise to get exactly what's asked, I wonder if this could be used https://tembo.io/blog/introducing-pg-later/ together with a trigger to trap the DROP, alert on Slack and run later if not aborted.


Migrations are not your safety net, backups are. Migrations, like all code, are full of bugs.


Don't give them the DROP permission and have them go through a (automated) process to elevate their privilege when they need it.


Modify your schema through migrations that go through code review :p


Haha, we need Neuralink chips then.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: