Azure App Service - Detect Shutdown - node.js

I have a Node.js app hosted as an App Service on Microsoft Azure. Periodically, it shuts down. I'm trying to understand when this occurs. In attempt to do this, I'm sending myself an email on certain events.
Currently, I'm sending an email to myself when the app starts. Then, I try to send an email when the app service stops. I'm attempting this using the following code:
const app = require('./app');
const port = 1337;
const server = app.listen(port);
// Respond to the server starting.
server.on('listening', function() {
sendEmail('App Service - Listening', 'Web site server listening');
});
server.on('close', function() {
sendEmail('App Service - Closed', 'Web site server closed.');
});
process.on ('SIGTERM', function() {
sendEmail('App Service - Exited', 'Process exited (via SIGTERM)');
});
process.on ('SIGINT', function() {
sendEmail('App Service - Exited', 'Process exited (via SIGINT)');
});
process.on('exit', function() {
sendEmail('App Service - Exited', 'Process exited');
});
Please assume the sendEmail function exists and works. As mentioned, I'm successfully getting an email when the app is listening. However, I never receive one when the app goes to sleep/stops listening.
Am I missing something?

If your post code is hosted on Azure Web Apps, you need to modify your port to process.env.port to make your node.js application run on Azure.
As Azure Web Apps use IIS to handle mapping scripts, and use a pipe port to translate http requests. And Azure Web Apps only expose 80 and 443 port to public.
Meanwhile, you can modify your prot to process.env.port||1337 to make it both run Azure and local.
update
Always On. By default, web apps are unloaded if they are idle for some period of time. This lets the system conserve resources. In Basic or Standard mode, you can enable Always On to keep the app loaded all the time. If your app runs continuous web jobs, you should enable Always On, or the web jobs may not run reliably.
You can config this setting on Azure portal:
refer to https://azure.microsoft.com/en-us/documentation/articles/web-sites-configure/ for more.

It could be an uncaught exception, try this one to catch them:
process.on('uncaughtException', function(err) {
console.log(err);
});

Related

Service Discovery in Cloud Run

I have two micro services on Google Cloud Run which are meant to communicate via gRPC
Products Service
Customer Service.
Product Service is started like below:
....
let server = new grpc.Server();
server.addService(products_proto.Product.service, {...});
server.bindAsync("0.0.0.0:50051", grpc.ServerCredentials.createInsecure(), () => {
server.start();
console.log('Product Service Started');
});
...
How can Product Service locate Customer Service in production without explicitly specifying the port?
Or do I have to always ask my colleagues to tell me the port they exposed their micro-service on?
Wouldn't that be a very tedious process?
I want my product service to connect to my customer service using something like
....
new customer_proto.Customer("customer-service", grpc.credentials.createInsecure());
....
Instead of
....
new customer_proto.Customer("0.0.0.0:50052", grpc.credentials.createInsecure());
....
Can this be achieved?

Application Error message when browsing Azure deployed web app

I created a simple web app (serverless) and deployed the web app using Azure App Service VS Code extension. I chose Linus + Node LTS environment. I configured deployment source to a local Git repo (also tried remote GitHub repo) and deployed. The deployment shows successful message. But when I browse the site, it throws a message (after 3-4 mins) that there was an ":( Application error". The admin diagnostics link doesn't show any error. Any reason why this could be happening?
Where can I find error details?
The web app compiles/runs fine on the local host.
Enable Log Streamming, then you'll be able to figure out what the problem is:
https://learn.microsoft.com/en-us/azure/app-service/troubleshoot-diagnostic-logs
As another option, you can also instrument your application with Application Insights:
https://learn.microsoft.com/en-us/azure/azure-monitor/app/nodejs
On Azure WebApps, the container/application must respond to HTTP pings on the required port (check docker run command in the Log Stream) within 230 seconds, by default.
For a NodeJS app, you'd need to start the server in the following way:
const port = process.env.PORT || 1337;
server.listen(port);
Try deploying the sample available here:
https://github.com/Azure-Samples/nodejs-docs-hello-world
If that does not help, enable App Service Logs and check for any errors in the Log Stream.
I had created a NodeJS app which integrates with Application Insights some days back:
https://github.com/gkgaurav31/nodejs-application-insights-test-app
change your listen port either 8080 or 1337
By default, NodeJS webapp runs on port 8080. You are either running your port on some other port (Ex: 3000 or so) and then deploying it to webapp. Try changing your port in NodeJS app to 8080 and it should work.

How can I execute terminal script/command in Google Compute Instance remotely from my React app?

Is it possible to execute a script remotely on Google Compute Engine (GCE) instance from my react app?
For example, I would upload a file to google cloud storage, then I have some script executed remotely that read the uploaded file and modify it (adding some metadata, etc.)
Is it possible at all?
For executing a script remotely, you have to be connected to the VM. For me, the easiest way is to deploy an endpoint on the VM (what ever is it, but think to secure it with SSL and authentication).
Then, call this endpoint with your react app. The endpoint can spawn scripts on the VM.
In case of storage, you can
Set an event that trigger a Cloud Function
The Cloud Function call the endpoint exposed on your VM
Plug a serverless VPC Connector to your function for reaching privately your VM (no public IP required). This is the most secure way.
UPDATE
Here the code to set on your vm:
const express = require('express');
const app = express();
var exec = require('child_process').exec;
app.get('/', (req, res) => {
//Change the script. Here it's pwd, set what you want
exec('pwd', function callback(error, stdout, stderr){
//Handle here the output of your bash script
res.send(stdout)
})
res.statusCode=200;
})
const port = process.env.PORT || 8080;
app.listen(port, () => {});
On your VM, install nodejs and express. Then run node index.js. You can customize the port by setting the env variable PORT at the value that you want. Else it's 8080 by default.
Open the required firewall rule to your VM for allowing a call to your express server.
Here there is neither SSL on the server nor authentication, even basic.

Running GraphQL server on Google Cloud App Engine

In node.js to run the endpoint locally, I use the following snippet in my app.js
app.use('/graphql', (0, _expressGraphql2.default)(function (req) {
return {
schema: _schema2.default,
pretty: true,
context: _extends({ db: _models2.default }, (0, _isUser2.default)(req.headers['authorization'].split(' ')[1]))
};
}));
app.listen(8080, function () {
However, my app isn't receiving any response from the endpoint on trying to reach hostname:8080/graphql. This works on my local machine.
The title of your post indicates that your node.js app is deployed in Google App Engine. There is no need to worry about assigning an IP address to your instance in that environment. Instances are managed by the App Engine, and so is the routing of requests to your application.
To access the app, once deployed to the App Engine, one only needs to address it following the pattern: app_name.appspot.com. Alternatively, for a custom domain, you can follow the “Using Custom Domains and SSL” guide [1]. Sub-chapter “Adding SSL to your custom domain” of this document may help you with the setting up of SSL, if needed.
The app listens on port 8080 by default in the app engine. This is of no concern to an outside caller, who can only use the following the pattern: app_name.appspot.com to call the app. This situation is valid for the app engine environment.
[1] https://cloud.google.com/appengine/docs/flexible/nodejs/using-custom-domains-and-ssl

socket.io client not connected to azure server created in socket.io

//this is my client code which is previously pointing to my local server which is on my Lan network.it work fine
//my server code i post on azure machine and run it run fine
//but it not connected to my below client
var socket = io.connect('http://104.222.195.120:4000');// azure ip add
socket.on('news', function (data) {//angular client for socket
$rootScope.top = JSON.parse(data);//top receive data
$scope.$apply(function () {
// $scope.newCustomers.push(data.customer);
// $scope.a1 = data;
});
});
//io.connect('http://104.222.195.120:4000') is need more than ip
If you're running your server in an Azure Web App, you're going to have issues because you're trying to listen on port 4000. Web Apps only allow for ports 80 and 443.
If you're running your server in an Azure VM, you have to open port 4000 to the outside world via network security group (or endpoint if doing a Classic VM deployment).

Resources