This is a situation that I first began to create tools to improve on what looks about a good 7 years ago.
The problem is a simple one. As a command line junkie I've got a lot of commands that I run on my computer and we've got a number of systems we can use to collect this information (the shell provides a mechanism by default), but things become increasingly more fraught the more requirements we start to pile onto the problem.
bash's default behavior stinks! It easily and regularly overwrites its own history file. In July 2013 I came up with a nice solution that lives on to this day. The principles continue to be relevant:
$@$ to separate fields, so it was like CSV except more like a DADSV (Dollar-At-Dollar separated
values). That's because commas can clearly be easily found in shell commands. Pretty much anything. So I wanted to make
something reasonably short but also weird enough not to see commonly. In terms of metadata I recorded stuff like: hist, that would consume this special ~/.zsh_enhanced_new_history file that I began using and renders it
into a better human readable format. It would nicely render the command back out in a central column and keep the
metadata from interfering with it. A semi-tabular way to review the data: 
This runs fast enough that it doesn't get bogged down by hundreds of thousands of history entries, so I continue to use this thing.
Now that in itself helped a lot, but I needed to go further for multiple machines. I wanted to have a similar solution for bash also but I figured if I care enough to improve bash, I could just set up zsh. Now that turned out not really a great assumption either.
Originally my big hammer solution to multiple machines and trying to work with logs that self-truncate was the following system:
hist.In practice this works, but is very inefficient. The git repo became impossibly huge.
So I finally hunkered down and made a proper attempt to do this the right way. I have only really the one North Star that I wanted to guide this one: Simplicity as an utmost priority. This means no databases, not even SQLite. I need text files, no more and no less.
So, the approach I'm taking is to enforce and rely on only ever appending. I will also double down on the preexec() hack
I used for zsh by leveraging PROMPT_COMMAND for the same under bash.
I am making a small bootstrapper system that I can use to deploy this configuration into ~/.bashrc the moment i'm able
to SSH into the machine.
The sync will be a hub and spokes model. The central computer is my main laptop machine and the process is the laptop has the cronjob that will cause it to go through and transfer the latest log content from configured machines via SSH.
This means I do a one time initialization on any environment that minimally interferes with its configuration or operation (just one line
added to bottom of .bashrc) and from then on my laptop will be able to periodically fetch the latest command history
content at any time that my laptop is able to reach it via SSH.