Zap stack traces vs. error messages on google cloud - go

I'm using zapp to log error messages on a service hosted on google cloud, and am seeing that while errors are logged successfully, the text stored in the "message" field of the google cloud log is the stack trace, and not the error message I have logged.
Example code:
var log *zap.Logger
if err := doStuff(); err != nil {
log.Error(<error message I want to log>, zap.Error(err))
}
This works well except google cloud logging and stackdriver will use the stack-trace caught by the call to zap.Error in the message field of the structured log. The message I've defined appears in the msg field, but the former appears to be the one displayed predominantly in the logging console and used by stackdriver for indexing errors.
This means that when navigating logs and errors via the console, I only see stacktraces, and no indication of the associated error string.
The tricky thing is I have no idea if this "issue" is cloud-side or zapp-side. I've spent some time digging around in Zapp to no avail, and am out of ideas.

zap by default puts the message under the msg key, the stacktrace under stacktrace, and prints log lines as json to stdout. You should be able to see this in action by just running your binary locally.
Your logging system presumably processes these log lines as they're printed. It will read them, parse them, and maybe do some restructuring or add some metadata, and then send them off somewhere else to be saved or processed more.
Since zap is in all likeliness working as intended, you need to look at the system that processes your logs. How does it expect them to look? Does it have special rules for any particular keys? Will it inject any keys of its own?
Note that you can configure zap to use different keys for all of its standard fields.

To log correctly and effectively on GCP, first, you have to set appropriate Zap keys with the Logging's LogEntry
In case you are looking for a working example, I write a simple Zap config here:
https://github.com/uber-go/zap/discussions/1110#discussioncomment-2955566

Related

GKE: Classify log messages based on tag in message payload

I have a third-party go based app that is writing logs to stderr. Even though the log message is written as an INFO message stackdriver classifies it as ERROR because the log message is written to stderr (which seems to be default for golang logger).
Below is an example of an INFO message, but logged as ERROR
textPayload: "2022-04-05T16:41:38.369Z INFO controller.CertificateRequest CertificateRequest is Ready, ignoring. {"certificaterequest": "elasticsearch/es-http-tls-trs4t", "cr": {"namespace": "elasticsearch", "name": "es-http-tls-trs4t"}} "
Is it possible reclassify log messages based on payload tags?
I would like to classify above message as an Info rather than error so my logging alerts doesn't go crazy
Here is an interesting link:
https://huynvk.dev/blog/4-tips-for-logging-on-gcp-using-golang-and-logrus
You should use logrus and hooks.
They work the same way as aspect-oriented programming in java.
Anyway logrus is in maintenance status on github.
Otherwise you could refer to Zap or Apex (logrus design based).
https://github.com/uber-go/zap
https://github.com/apex/log

Cannot see the logs on Kibana in the logs tab

I am running my project and after creating the index pattern and adding the log indices under the settings tab and applying it to save the changes. I go to the stream and for some reason I do not see anything in it. I then try using postman to use the get method to cause the messages to load in the logs stream but it does not. Is there a reason why that I cannot see it?
This is the logs in the discover section:
I then have the indice in the settings applied so it should populate:
But when I go to stream it does not show up, even on live streaming and using postman to send it.

How to debug HyperLedger Composer Transaction code in Playground

I am using a local install of Playground on MacOS.
I was successful to create my business network, add my model file and logic to this network and create assets and participants instances.
So now I am ready to submit my first transaction, but I get an error message in the popup window as a result to my request. The message per se is not the problem (it's about some Undefined asset), my problem is I want to debug this transaction code by producing some execution traces, using old-school printf or log message.
I tried to insert console.log(message) instructions in my transaction code but eventually I was not able to retrieve those logs traces (eg. using a command like docker logs -f composer).
Is there another way to produce logs traces? Or did I miss a config setting to defilter logs in docker logs?
Any help greatly appreciated!
Olivier.
On console logging (and seeing them in the browser Developer console), see this Stack Overflow here (hyperledger composer playground) Can you see results of console.log('something') in browser? (it also has a link to more info there
See here https://hyperledger.github.io/composer/latest/problems/diagnostics.html for more on logging / where to find debug logs.
As for setting checkpoint/breakpoints: These are set by the Editor tooling 🙂 In H/Composer, you can just use the embedded connector (eg such as TP functions) to try out / step through each breakpoint - for more info on VSCode -> https://code.visualstudio.com/docs/editor/debugging and Atom -> How do I set a breakpoint inside of atom's package? and I posted the link to diagnostics/logging above.
One quick way I used to insert breakpoints with debug messages, is to throw an exception using throw new Error(...) in the transaction method.
This shows up in the playground interface as well.

How to log errors when Play Evolutions fail?

I am just getting started with Play Evolutions and I find it pretty tough to figure out why they fail and leave the DB in an inconsistent state.
In Dev mode it will display the error in the default HTML page but it does not say which statement failed. This is also problematic since for this particular application I only have REST APIs that return JSON and so an HTML error is not appropriate. I have my own error handler so I will probably end up matching on ExceptionAttachment and pull out the content/script myself and escape that in the JSON error response. However this is only in DEV mode since I would not want this going back to a real user in PROD.
More frustrating is that it doesn't even log the statement when it fails. I can enable logging for my driver but once the failure has occurred it is too late to then go and enable logging.
Is there anyway to get a more specific error in the logs when an evolution fails?

Controlling which script is logged in system logs based on verbosity level in service now

The organisation I work in uses service Now ,I just joined the team, My team wants me to do some research on logging in Service now.
All they want is to control the logging of scripts when they write a script on the server based on the verbosity level of the script
My understanding on logging is it the type of process that takes place on the server i.e
•if a script is not of a proper syntax it logs as a WARNING stating the compile error in the message of the log
•If something runs successfully or a process is completed, it logs as INFO with the message of what happened
•Similar logging for debug takes place, (I may be wrong about this though)
I tried searching on service now wiki,one method I found was gs.log()
I tried running some test script to log info in System Definition > Scripts - Background
Some of the various scripts I tried where
var gl = new GSLog("com.snc.sla.tasksla.log", "TaskSLA");
gl.logErr("This is an error message");
var gl = new GSLog("com.snc.sla.tasksla.log", "TaskSLA");
gl.logWarning("This is a warning message");
gs.info("This is an info log");
gs.debug("This is a debug log");
And then searched in the logs table System Logs > System Log > All
all is saw was the scripts I ran were logged as whole with INFO as the level , if the scripts had a syntax error it logged the same with WARNING level
Why doesn't it log the script line by line?
Also is there a way where I can tell Service now what script it should log based on the verbosity level?
If you're on the Fuji release or newer (which is still pretty new, so you may not be), there's actually a whole new logging api that's a bit more intuitive, and it's application-based. What follows is the documentation for that API:
Verbosity
There are 4 levels of verbosity, in order from least verbose to most verbose, they are:
error (gs.error)
warn (gs.warn)
info (gs.info)
debug (gs.debug)
...this means that setting log-level for a particular app to "info" will give you info+warn+error, but NOT debug.
...Session debugging verbosity is debug, so any level of log verbosity will be included in Session debug output, for JUST the app being debugged IN the session with session debugging activated.
The property for logging verbosity is (replacing with your app name):
<APP_NAME>.logging.verbosity // off -> error -> warn -> info -> debug
Destination
Log destination of "db" will route log messages within desired logging verbosity to the table "syslog_app_scope", which extends syslog. This new table has added fields for the App/Scope issuing the log as well as a Source Script field that links to the script that called into the logging API (when we can figure it out, currently just for Business Rules and Script Includes). When Destination is set to "db", logs will ALSO go to file system.
Log destination of "file" will log to the node's file system log without broadcasting to log listeners (except in the case of Scripts-Background)
The property for destination is:
<APP_NAME>.logging.destination // none -> file -> db (implies file also)
Usage Examples
Consumers of this API (from JavaScript) should be able to just do:
gs.debug(message [, parameters])
-emit log message at debug level verbosity
gs.info(message [, parameters])
-emit log message at info level verbosity
gs.warn(message [, parameters])
-emit log message at warn level verbosity
gs.error(message [, parameters])
-emit log message at error level verbosity
This logging API supports the java MessageFormat placeholder replacement pattern
Currently there is support for up to 5 "varargs" placeholder arguments, any more than 5 need to be specified as a single javascript array argument
All of these are legal calls:
gs.info("Here's a log message from me"); // no params
gs.info("Here's a log message from {0}", myName); // single non array param
gs.info("Here's a log message from {0}.{1}", myFirstName, myLastName); // multiple "varargs" params (up to 5!)
gs.info("Here's a log message from {0}.{1}", [myFirstName, myLastName]); // array of n-number of params (no upper bounds)

Resources