Live updating Node.js logging configuration - node.js

What I'm trying to accomplish:
Update the logging level on a node micro service, without stopping the existing running service, by detecting the saving of a change to the config file.
The reason: work policies demand different levels of approval based on what gets changed.
Updating a config file is a "standard change" (considered "safe", requiring low ceremony to accomplish.)
Changing the config file, and restarting the service is a "normal change" (considered "not safe", requiring vp approval).
This capability will go a long way towards allowing us to improve the logging in our services.
The technical challenge:
Both node-config and bunyan appear to require a restart in order to accept changes.
Results of attempting to do proper research prior to submitting a question:
Live updating Node.js server
Can node-config reload configurations without restarting Node?
(This last post has a solution that worked for someone, but I couldn't get it to work.)
In theory, I should be able to delete both the app level objects using the lines:
delete require.cache[require.resolve('config')];
delete require.cache[require.resolve('logging')];
and then recreate both objects with the new configurations read from the changed config file.
Deleting the config and logging object may work, but I'm still a node nube so every way that I attempted to use this magical line failed for me.
(Caveat: I was able to delete the objects I just couldn't get them recreated in such a way that my code would use the newly created objects.)
The horrifically ugly attempt of what I'm doing can be found on my github in the "spike_LiveUpdate" directory of:
https://github.com/MalcolmAnderson/uService_stub
The only thing we are attempting to change is the log level of the application so that, if we needed to, we could:
bounce the logging level "to 11" for a small handful of minutes,
have the user demonstrate their error,
and the put it back to the normal logging level.
(It would also be a useful tool to have in our back pocket so when the dealers of FUD say, "But if you get the logging level wrong, we will have to use an emergency change to fix it. Sorry, we appreciate your desire to get a better picture of what's happening in the application, but we just can't justify the risk you're proposing.")
Research prior to writing question:
Attempt to solve the problem.
Search for "node live update", "node live configuration update", "node no restart configuration change"
Search for the above but replacing the word "live update" with "rolling update" (this got a lot of Kubernetes hits, which may be the way I have to go with this.)
Bottom line: Attempting to be able to change both Node-config, and Bunyan logging without a restart.
[For all I know, there's a security reason for not allowing live updates.]

If I understand truly, you need to change log level of your application but without restart it
According to this, there are couple of ways I can suggest.
You can create a second server which includes the new deployment of your changed code and route new traffic to the new server and stop routing new traffic to the old server. When old server drains the processes it currently has, you can shut it down and go with a new one, or re-deploy your application for normal status.
You can create a second application layer in the same server with different port which I do not recommend it and do the same thing with first bullet that I mentioned.
If you're not running on Kubernetes, you need to make your own rolling update strategy (k8s is doing it automatically).

Related

"Database" files are overriden in Heroku

I am trying to avoid using a DB in my simple RESTful app.
I created a "posts.txt" file which has all the posts in it, the app reads from this file and creates the posts array (JSON.parse).
The problem is, when I "git push heroku master" it, the "posts.txt" in heroku gets overriden and thus I lose all the posts created by guests.
I tried to .gitignor this file but it seems I just do it worng (or that I didn't understand the idea of "untracking" a file).
What can I do in order to prevent the overriding (I just don't want to push a new "posts.txt" into heroku every time)?
Due to your Heroku app potentially being run on multiple servers over time, there is no way to ensure that your posts.txt file will remain consistent overtime. Also as you make changes, and as you have noted, it can easily get overwritten.
Heroku can terminate your application and start it on another server as needed. Almost like a server-less type setup.
That means there is no real way to ensure a stable data persistence on Heroku without some type of database layer.
Great point mentioned in the comments that I forgot to mention. The file will also be deleted after cycling because the filesystem is ephemeral. You can find more information about file uploads missing/deleted on Heroku's site here.
One other thing about this is even you are using some type of VPS or something like that, you'd still run into the problem of how to sync the posts down to your local machine during development and ensuring that stays in sync. Database layer is for sure the way to go here.

What's the process of updating a NodeJS running in production?

I am working on a webapp that will be published in production and then updated on regular basis as features and bug fixes are coming.
I run it like node app.js which loads config, connects to database, starts web server.
I wonder, what's the process of updating the app when I have next version?
I suppose, I have to kill the process and start after update and deploy? It means, that there will be some downtime?
Should I collect stats on the least use during the week/month and apply the update during that period? Or should I start the current version on another machine, redirect all requests to it and update the main one, then switch back?
I think the second approach is better.
The first one won't prevent downtime, it will just make sure it impacts the least number of users, while the second one creates no down-time at all.
Moreover, I think you should keep the old version running in the other machine for some time in case you will find out the new version must be reverted due to whatever reason. In that case you will just have to redirect traffic to the old node without any downtime.
Also, if you're setting up production environment I would recommend that instead of just running your process with "node" command, you will use something like forever or pm2 in order to do automatic restarts and some other advanced features.

When should an Azure website be restarted, and what are the consequences?

In the Azure Management Portal, you can configure your website. As an example, you can change the PHP version your website is using. When you have edited a configuration option, you have to click “Save”.
So far, so good. But you also have the option to restart your site (by clicking “Restart“ next to “Save”).
My question is, when should you restart your website? Are there some configuration changes that require a restart, and others that don't? I haven't found any hints in the user interface.
Are there other situations that require a restart? Say, the website has been running for a given time without a restart?
Also, what are the consequences of restarting a website? Does it affect cookies/sessions in any way (i.e. delete a user's shopping cart or log them out)? Are there any other consequences I should be aware of?
Generally speaking, you may want to restart your website because of application performance issues. For example, you may have a memory leak in your application, connections not getting closed, or other things that would degrade the performance of the application over time. As you monitor your website and observe conditions like this you may make a decision to restart it. Even better, you may even automate the task of restarting when these conditions occurr. Anyway, these kinds of things are not unique to Azure Websites. You would take similar actions for a website running on-premises.
As for configuration changes, if you make a change to your web.config file, this change is detected and your website would be restarted automatically for you. Similarily, if you were to make configuration changes in the CONFIG page of your website in the Azure Management Portal such as application settings, connection strings, etc., then Azure Websites will detect this change to your environment and automatically restart it.
Indeed, restarting a website will result in any session data kept in memory being lost for that instance. Additionally, if you have startup/initialization code that takes time to complete then that will have to be rerun. Again, this is not anything unique to Azure Websites though.

FluentMigrator Migration From Application_Start

I am currently changing our database deployment strategy to use FluentMigration and have been reading up on how to run this. Some people have suggested that it can be run from Application_Start, I like this idea but other people are saying no but without specifying reasons so my questions are:
Is it a bad idea to run the database migration on application start and if so why?
We are planning on moving our sites to deploying to azure cloud services and if we don't run the migration from application_start how should/when should we run it considering we want to make the deployment as simple as possible.
Where ever it is run how do we ensure it is running only once as we will have a website and multiple worker roles as well (although we could just ensure the migration code is only called from the website but in the future we may increase to 2 or more instances, will that mean that it could run more than once?)
I would appreciate any insight on how others handle the migration of the database during deployment, particularly from the perspective of deployments to azure cloud services.
EDIT:
Looking at the comment below I can see the potential problems of running during application_start, perhaps the issue is I am trying to solve a problem with the wrong tool, if FluentMigrator isn't the way to go and it may not be in our case as we have a large number of stored procedures, views, etc. so as part of the migration I was going to have to use SQL scripts to keep them at the right version and migrating down I don't think would be possible.
What I liked about the idea of running during Application_Start was that I could build a single deployment package for Azure and just upload it to staging and the database migration would be run and that would be it, rather thank running manual scripts, and then just swap into production.
Running migrations during Application_Start can be a viable approach. Especially during development.
However there are some potential problems:
Application_Start will take longer and FluentMigrator will be run every time the App Pool is recycled. Depending on your IIS configuration this could be several times a day.
if you do this in production, users might be affected i.e. trying to access a table while it is being changed will result in an error.
DBA's don't usually approve.
What happens if the migrations fail on startup? Is your site down then?
My opinion ->
For a site with a decent amount of traffic I would prefer to have a build script and more control over when I change the database schema. For a hobby (or small non-critical project) this approach would be fine.
An alternative approach that I've used in the past is to make your migrations non-breaking - that is you write your migrations in such a way they can be deployed before any code changes and work with the existing code. This way both code and migrations both can be deployed independently 95% of the time. For example instead of changing an existing stored procedure you create a new one or if you want to rename a table column you add a new one.
The benefits of this are:
Your database changes can be applied before any code changes. You're then free to roll back any breaking code changes or breaking migrations.
Breaking migrations won't take the existing site down.
DBAs can run the migrations independently.

Deploying updates to production node.js code

This may be a basic question, but how do I go about effeciently deploying updates to currently running node.js code?
I'm coming from a PHP, JavaScript (client-side) background, where I can just overwrite files when they need updating and the changes are instantly available on the produciton site.
But in node.js I have to overwrite the existing files, then shut-down and the re-launch the application. Should I be worried by potential downtime in this? To me it seems like a more risky approach than the PHP (scripting) way. Unless I have a server cluster, where I can take down one server at a time for updates.
What kind of strategies are available for this?
In my case it's pretty much:
svn up; monit restart node
This Node server is acting as a comet server with long polling clients, so clients just reconnect like they normally would. The first thing the Node server does is grab the current state info from the database, so everything is running smoothly in no time.
I don't think this is really any riskier than doing an svn up to update a bunch of PHP files. If anything it's a little bit safer. When you're updating a big php project, there's a chance (if it's a high traffic site it's basically a 100% chance) that you could be getting requests over the web server while you're still updating. This means that you would be running updated and out-of-date code in the same request. At least with the Node approach, you can update everything and restart the Node server and know that all your code is up to date.
I wouldn't worry too much about downtime, you should be able to keep this so short that chances are no one will notice (kill the process and re-launch it in a bash script or something if you want to keep it to a fraction of a second).
Of more concern however is that many Node applications keep a lot of state information in memory which you're going to lose when you restart it. For example if you were running a chat application it might not remember who users were talking to or what channels/rooms they were in. Dealing with this is more of a design issue though, and very application specific.
If your node.js application 'can't skip a beat' meaning it is under continuous bombardment of incoming requests, you just simply cant afford that downtime of a quick restart (even with nodemon). I think in some cases you simply want a seamless restart of your node.js apps.
To do this I use naught: https://github.com/superjoe30/naught
Zero downtime deployment for your Node.js server using builtin cluster API
Some of the cloud hosting providers Node.js (like NodeJitsu or Windows Azure) keep both versions of your site on disk on separate directories and just redirect the traffic from one version to the new version once the new version has been fully deployed.
This is usually a built-in feature of Platform as a Service (PaaS) providers. However, if you are managing your servers you'll need to build something to allow for traffic to go from one version to the next once the new one has been fully deployed.
An advantage of this approach is that then rollbacks are easy since the previous version remains on the site intact.

Resources