Zorik
Zorik

Reputation: 237

Simplest way to perform logging from Google Cloud Run

I followed this guide https://firebase.google.com/docs/hosting/cloud-run to setup cloud run docker. Then I tried to follow this guide https://cloud.google.com/run/docs/logging to perform a simple log. Trying to write a structured log to stdout This is my code:

    trace_header = request.headers.get('X-Cloud-Trace-Context')

    if trace_header:
        trace = trace_header.split('/')
        global_log_fields['logging.googleapis.com/trace'] = "projects/sp-64d90/traces/" + trace[0]

    # Complete a structured log entry.
    entry = dict(severity='NOTICE',
                 message='This is the default display field.',
                 # Log viewer accesses 'component' as jsonPayload.component'.
                 component='arbitrary-property',
                 **global_log_fields)

    print(json.dumps(entry))

I cannot see this log in the Cloud Logs Viewer. I do see the http Get logs each time I call the docker. Am I missing anything? I am new to this and wondered what is the simples way to be able to log information and view it assuming the docker I created was exactly with the steps from the guide (https://firebase.google.com/docs/hosting/cloud-run)

Thanks

Upvotes: 14

Views: 19595

Answers (5)

DfreakD
DfreakD

Reputation: 51

An easy way to integrate Google Cloud Platform logging into your Python code is to create a subclass from logging.StreamHandler. This way logging levels will also match those of Google Cloud Logging, enabling you to filter based on severity. This solution also works within Cloud Run containers.

Also you can just add this handler to any existing logger configuration, without needing to change current logging code.

import json
import logging
import os
import sys
from logging import StreamHandler

from flask import request


class GoogleCloudHandler(StreamHandler):
    def __init__(self):
        StreamHandler.__init__(self)

    def emit(self, record):
        msg = self.format(record)
        # Get project_id from Cloud Run environment
        project = os.environ.get('GOOGLE_CLOUD_PROJECT')

        # Build structured log messages as an object.
        global_log_fields = {}
        trace_header = request.headers.get('X-Cloud-Trace-Context')

        if trace_header and project:
            trace = trace_header.split('/')
            global_log_fields['logging.googleapis.com/trace'] = (
                f"projects/{project}/traces/{trace[0]}")

        # Complete a structured log entry.
        entry = dict(severity=record.levelname, message=msg)
        print(json.dumps(entry))
        sys.stdout.flush()

A way to configure and use the handler could be:

def get_logger():
    logger = logging.getLogger(__name__)

    if not logger.handlers:
        gcp_handler = GoogleCloudHandler()
        gcp_handler.setLevel(logging.DEBUG)

        gcp_formatter = logging.Formatter(
            '%(levelname)s %(asctime)s [%(filename)s:%(funcName)s:%(lineno)d] %(message)s')
        gcp_handler.setFormatter(gcp_formatter)
        logger.addHandler(gcp_handler)
    return logger

Upvotes: 3

Onkar
Onkar

Reputation: 354

#For Python/Java

Using "google-cloud-logging" module is the easiest way to push container logs to Stackdriver logs. COnfigure google-cloud-logging to work with python's default logging module

import logging as log
import google.cloud.logging as logging

def doSomething(param):
    logging_client = logging.Client()
    logging_client.setup_logging()
log.info(f"Some log here: {param}") 

now you should see this log in Stackdriver logging under Cloud Run Revision.

Upvotes: 9

offlinemark
offlinemark

Reputation: 321

I am running into the exact same issue. I did find that flushing stdout causes the logging to appear when it otherwise would not. Looks like a bug in Cloud Run to me.

print(json.dumps(entry))
import sys
sys.stdout.flush()

Output with flushing

Upvotes: 14

marian.vladoi
marian.vladoi

Reputation: 8074

1.Follow the guide you mentioned Serve dynamic content and host microservices with Cloud Run

2.Add the following code to index.js

 const {Logging} = require('@google-cloud/logging');
 const express = require('express');
 const app = express();

 app.get('/', (req, res) => {
  console.log('Hello world received a request.');

  const target = process.env.TARGET || 'World';
  const projectId = 'your-project';
  const logging = new Logging({projectId});

  // Selects the log to write to
  const log = logging.log("Cloud_Run_Logs");

  // The data to write to the log
  const text = 'Hello, world!';

  // The metadata associated with the entry
  const metadata = {
    resource: {type: 'global'},
    // See: https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#logseverity
    severity: 'INFO',
  };

  // Prepares a log entry
  const entry = log.entry(metadata, text);

   async function writeLog() {
    // Writes the log entry
    await log.write(entry);
    console.log(`Logged the log that you just created: ${text}`);
  }
  writeLog();




  res.send(`Hello ${target}!`);
});

const port = process.env.PORT || 8080;
app.listen(port, () => {
  console.log('Hello world listening on port', port);
});
   

3.Check the logs under Logging/Global

enter image description here

Edit

For python:


import os
import google.cloud.logging
import logging


from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    target = os.environ.get('TARGET', 'World')
    # Instantiates a client
    client = google.cloud.logging.Client()

    # Connects the logger to the root logging handler; by default this captures
    # all logs at INFO level and higher
    client.setup_logging()

    # The data to log
    text = 'Hello, these are logs from cloud run!'

    # Emits the data using the standard logging module
    logging.warning(text)
    return 'Hello {}!\n'.format(text)

enter image description here

Upvotes: 1

ahmet alp balkan
ahmet alp balkan

Reputation: 45312

There is support for Bunyan and Winston node.js libraries in Google Cloud Loggging:

Typically, if you are not looking to do structured logging, all you need to do is print things to stdout/stderr and Cloud Run will pick it up.

This is documented at https://cloud.google.com/run/docs/logging and it has Node.js example for structured and non-structured logging as well.

Upvotes: -1

Related Questions