How to debug a not starting up Cumulocity Microservice written in Python? - python-3.x

How to enable log for microservice developped in Python?
I can run hello-microservice without a glitch. However, my own microservice looks not starting up after I uploaded the zip file. I tried to wait for hours, and the same. I have run the docker locally without issue.
A call to any REST end point of the microservice returns,
{"error":"Microservice/Bad gateway","message":"Microservice not available Connection refused : Connection refused: a2c-microservice-scope-xxx-prod.svc.cluster.local/80","info":"https://www.cumulocity.com/guides/reference-guide/#error_reporting"}
I assume for some reason, the microservice I uploaded didn't start up properly. How can I enable any log to find out where goes wrong?

You just need to logg to stdout and then you can access the logs through the user interface in Cumulocity IoT. It is available through the application UI in administration
Here a python example how to configure the logging:
LOG_FORMATTER = logging.Formatter("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s")
LOGGER = logging.getLogger()
LOGGER.setLevel(logging.DEBUG)
CONSOLE_HANDLER = logging.StreamHandler(sys.stdout)
CONSOLE_HANDLER.setFormatter(LOG_FORMATTER)
LOGGER.addHandler(CONSOLE_HANDLER)

Related

How to implement XRay in NodeJS project?

I've a nodejs project with Docker and ECS in AWS and i need to implement XRay to get the traces but I couldn't get it to work yet
I installed 'aws-xray-sdk' (npm install aws-xray-sdk), then I added
const AWSXRay = require('aws-xray-sdk');
in app.js
Then, before the routes I added
app.use(AWSXRay.express.openSegment('Example'));
and after the routes:
app.use(AWSXRay.express.closeSegment());
I hit some endpoints but I can't see any trace or data in xray, maybe do I need to setup something in AWS ? I have a default group in xray.
Thanks!
It sounds like you do not have the XRay Daemon running in your ECS environment. This daemon must be used in conjunction with the SDKs to send the trace data to AWS XRay service from the SDKs. The daemon listens for the trace data traffic on UDP port 2000. Read more about the daemon here:
https://docs.aws.amazon.com/xray/latest/devguide/xray-daemon.html
See how to run the XRay Daemon on ECS via Docker here:
https://docs.aws.amazon.com/xray/latest/devguide/xray-daemon-ecs.html
You would either need to look at X-Ray SDK, Agent or Open Telemetry SDK, Collector (AWS Distro for Open Telemetry)

Google Cloud loggin doesn't log all messages

I have a small program running on google app engine, I am using this function to write logs, in python 3.7:
def write_entry(text="", severity="", log_dict={}):
"""Writes log entries to the given logger."""
logging_client = logging.Client()
auth_data = auth().data_values
logger = logging_client.logger(auth_data['LOGGER_NAME'])
if not log_dict:
# Simple text log with severity.
logger.log_text(text, severity=severity)
if log_dict:
logger.log_struct(log_dict)
I've tested the program using this function from localhost with ngrok and the logs were collected.
After I've uploaded the code to app engine it only writes the first log, no other logs is collected. Does it need some permission in google app engine to work properly?

Stackdriver-trace on Google Cloud Run failing, while working fine on localhost

I have a node server running on Google Cloud Run. Now I want to enable stackdriver tracing. When I run the service locally, I am able to get the traces in the GCP. However, when I run the service as Google Cloud Run, I am getting an an error:
"#google-cloud/trace-agent ERROR TraceWriter#publish: Received error with status code 403 while publishing traces to cloudtrace.googleapis.com: Error: The request is missing a valid API key."
I made sure that the service account has tracing agent role.
First line in my app.js
require('#google-cloud/trace-agent').start();
running locally I am using .env file containing
GOOGLE_APPLICATION_CREDENTIALS=<path to credentials.json>
According to https://github.com/googleapis/cloud-trace-nodejs These values are auto-detected if the application is running on Google Cloud Platform so, I don't have this credentials on the gcp image
There are two challenges to using this library with Cloud Run:
Despite the note about auto-detection, Cloud Run is an exception. It is not yet autodetected. This can be addressed for now with some explicit configuration.
Because Cloud Run services only have resources until they respond to a request, queued up trace data may not be sent before CPU resources are withdrawn. This can be addressed for now by configuring the trace agent to flush ASAP
const tracer = require('#google-cloud/trace-agent').start({
serviceContext: {
service: process.env.K_SERVICE || "unknown-service",
version: process.env.K_REVISION || "unknown-revision"
},
flushDelaySeconds: 1,
});
On a quick review I couldn't see how to trigger the trace flush, but the shorter timeout should help avoid some delays in seeing the trace data appear in Stackdriver.
EDIT: While nice in theory, in practice there's still significant race conditions with CPU withdrawal. Filed https://github.com/googleapis/cloud-trace-nodejs/issues/1161 to see if we can find a more consistent solution.

#google-cloud/logging-winston not logging from NodeJS after some time inside a GCE instance

Node: 10.16.0
#google-cloud/logging-winston: 2.0.0
Server: GCE VM Instance
I'm logging to stackdriver from my node process running an a GCE instance. I'm adding the following object to my winston transports
new require("#google-cloud/logging-winston").LoggingWinston({
projectId: "my-google-project-id"
})
After deployment to GCP and starting the node process, I'm getting the logs in GCP Logs Viewer. So far so good. After a couple of hours(or in some cases minutes), I stop getting any logs in the Log Viewer. When I check the node process on my VM Instance, it is still running and writing logs to the console. But the google-cloud transport does not work at all. If I stop the node process and start a new one again, I start getting logs on the Logs Viewer again. But again it stops logging after some time. I tried downgrading from #google-cloud/logging-winston#2.0.0 to 1.1.1, but still the same. Could it be that I'm hitting some quotas? Or could it be because there is some uncaught error and #google-cloud/logging-winston fails from thereon?
In some instances it's possible that the some logs are skipped due to permission related issues. Make sure that your service account has the appropriate permissions [1].
Here is our documentation on how to set up Winston, just in case it had not crossed your eyes [2].
[1] https://cloud.google.com/logging/docs/agent/troubleshooting#verify-creds
[2] https://cloud.google.com/logging/docs/setup/nodejs#using_winston

Winston not logging at any log level, what could be wrong?

I have run in to a weird bug and don't know how to proceed/debug. I have an app that's written in Nodejs and uses Winston for logging. Everything was working fine until I brought up a new production server yesterday and retired the old one.
My prod server has 4 Nodejs processes running. On the new production server, Winston logs the very first log message per .js file, period. It stops logging after that, and changing the log level doesn't work. My app has got about 6 .js files, and in case of any error on any of those files, the very first error message gets logged but any subsequent errors/warning/info are not logged.
The funny thing is Winston was working just fine on the old prod server and the dev server still works fine.
I am on Winston 0.6.2 on both dev and prod. As far as I know, all the sw packages are the same between dev and prod.
How can I debug this issue?
After some research, I came across this issue => https://github.com/flatiron/winston/issues/227
Looks like, the new way of handling streams in the latest version of node has broken file transport in winston. I am going back to node v0.8.22 for the time being as a work around.
What transports are you using for logging? Does the console transport work? Perhaps the new production server has a network issue that prevents it logging to a remote service such as CouchDB or Loggly.
If you add a simple console.log('...') line next to your winston log lines do those get fired. This will confirm or deny that your winston log lines are getting called on the production server
winston.info('winston log test')
console.log('console log test')
You can can expose the logger instance and have a URL to trigger the required log level.
I had the same need so I came up with a dynamic log level setter for Winston https://github.com/yannvr/Winston-dynamic-loglevel

Resources