AppEngine: Get current serving application version - google-app-engine

Is there a simple way to get the current serving application version in AppEngine?

os.environ['CURRENT_VERSION_ID']

String version = SystemProperty.version.get();
String applicationVersion = SystemProperty.applicationVersion.get();
This is the syntax:
public static final SystemProperty applicationVersion
The major version number for the currently running version of the application plus a timestamp at which it was deployed. Has the key, "com.google.appengine.application.version".
See here
PS. One puzzle still remains. What does timestamp next to version means and how to read it??
EDIT: Here is the key to the mystery.
Date UploadDate = new Date(Long.parseLong(
applicationVersion.substring(applicationVersion.lastIndexOf(‌​".")+1))
/ (2 << 27) * 1000);

For Python (GAE SDK release: "1.4.2")
version_id = self.request.environ["CURRENT_VERSION_ID"].split('.')[1]
timestamp = long(version_id) / pow(2,28)
version = datetime.datetime.fromtimestamp(timestamp).strftime("%d/%m/%y %X")
See http://groups.google.com/group/google-appengine-python/browse_thread/thread/f86010e7cf3c71b4

from google.appengine.api import modules
modules.get_current_version_name()
Source: https://cloud.google.com/appengine/docs/python/modules/functions

For nodejs, I am not sure if this is documented.
process.env.GAE_VERSION

You can also access the process' environment variables:
GAE_VERSION
which is available when you deploy (gcloud app deploy) using the flag --version

For those who want an update, environment variables set for a GAE instance as of September 2020:
GAE_VERSION is the one that seems to answer the original question.
Google doc:
https://cloud.google.com/appengine/docs/standard/python3/runtime#environment_variables
The following environment variables are set by the runtime:
Environment variable Description
GAE_APPLICATION The ID of your App Engine application. This ID is prefixed with 'region code~' such as 'e~' for applications deployed in Europe.
GAE_DEPLOYMENT_ID The ID of the current deployment.
GAE_ENV The App Engine environment. Set to standard.
GAE_INSTANCE The ID of the instance on which your service is currently running.
GAE_MEMORY_MB The amount of memory available to the application process, in MB.
GAE_RUNTIME The runtime specified in your app.yaml file.
GAE_SERVICE The service name specified in your app.yaml file. If no service name is specified, it is set to default.
GAE_VERSION The current version label of your service.
GOOGLE_CLOUD_PROJECT The Cloud project ID associated with your application.
PORT The port that receives HTTP requests.

Based on my experiments today, there are two os.environ variables that you can use to get the current app version:
os.environ['GAE_VERSION']: the version name only
os.environ['CURRENT_VERSION_ID']: a unique version identifier composed of {version name}.{deployment id}, which is equivalent to os.environ['GAE_VERSION'] + '.' + os.environ['GAE_DEPLOYMENT_ID']
It appears that the so-called "deployment id" can be right-shifted 28 bits to get a timestamp in epoch seconds (as other answers already described).
For example: I deployed version "101" of my app at 2021-03-04T00:17:12Z and I'm seeing the following values:
os.environ['GAE_VERSION']: '101'
os.environ['CURRENT_VERSION_ID']: '101.433474146608888597'
os.environ['GAE_DEPLOYMENT_ID']: '433474146608888597'
You can use the following code to get the version name and timestamp from os.environ['CURRENT_VERSION_ID']:
>>> import os
>>> import datetime
>>> version_id = os.environ['CURRENT_VERSION_ID'] # example: '101.433474146608888597'
>>> name, ts = version_id.split('.')
>>> dt = datetime.datetime.utcfromtimestamp(int(ts) >> 28))
>>> dt.isoformat()
'2021-03-04T00:17:12'
Disclaimer: Most of this functionality is undocumented and the deployment ID format may be subject to change.

Related

How to get the project id in IBM Watson?

How do I get the project ID of my project in IBM Watson so that I access a data source?
This is documented here : https://www.ibm.com/docs/en/cloud-paks/cp-data/4.0?topic=lib-watson-studio-python
from ibm_watson_studio_lib import access_project_or_space
wslib = access_project_or_space()
project_name = wslib.here.get_name()
wslib.show(project_name)
project_id = wslib.here.get_ID()
wslib.show(project_id)
Example
The old project-lib has been deprecated. See Deprecation Announcement https://www.ibm.com/docs/en/cloud-paks/cp-data/4.0?topic=notebook-using-project-lib-python-deprecated
In the project homepage url, the project id is the alphanumeric string just after the '/proj/". Copy it and use it as the project id.

Get env value to model laravel?

I have problem with date format in laravel model for different operating system (windows & linux) SQL Server
How to get the value from env to model, I create variable in .env for set condition in model when value variable environment 1 = windows and 2 = linux
// 1 FOR WINDOWS
// 2 FOR LINUX SERVER
ENVIRONMENT=1
Any solution / advice for this case?
All variables in your .env files are parsed as strings, so some reserved values have been created to allow you to return a wider range of types from the env() function.
make sure you already execute this command to clear your config after you added that variable to your config.
php artisan config:clear
Retrieving Environment Configuration
<?php
$environment = env("environment", 1)
?>
The second value passed to the env function is the "default value". This value will be used if no environment variable exists for the given key.
see docs here env
in Laravel function env() returns values from .env file.
So if you have ENVIROMENT = 1 in your .env, using env('ENVIRONMENT'), you will get that value.

Get current deployed timestamp in AppEngine/Go

Can I get the deployed timestamp of current application version in AppEngine/Go?
It seems helpful, but not sure how to implement in AppEngine/Go application code.
AppEngine: Get current serving application version
https://godoc.org/google.golang.org/appengine
https://cloud.google.com/appengine/docs/admin-api/v1beta2/reference/apps/modules/versions
From this link AppEngine: Get current serving application version, the suggested answer is written in python
os.environ['CURRENT_VERSION_ID']
Above code is trying to retrieve the environment variable with name CURRENT_VERSION_ID, Equivalent code in go would be:
import (
...
"os"
)
...
versionText := os.Getenv("CURRENT_VERSION_ID")
According to one of the comments, the result would be in this format my-version.383096322806301043, you should use strings.Split method to split it by ., eg:
import (
...
"strings"
)
...
timestampString := strings.Split(versionText, ".")[1]

How to view JSON logs of a managed VM in the Log Viewer?

I'm trying to get JSON formatted logs on a Compute Engine VM instance to appear in the Log Viewer of the Google Developer Console. According to this documentation it should be possible to do so:
Applications using App Engine Managed VMs should write custom log
files to the VM's log directory at /var/log/app_engine/custom_logs.
These files are automatically collected and made available in the Logs
Viewer.
Custom log files must have the suffix .log or .log.json. If the suffix
is .log.json, the logs must be in JSON format with one JSON object per
line. If the suffix is .log, log entries are treated as plain text.
This doesn't seem to be working for me: logs ending with .log are visible in the Log Viewer, but displayed as plain text. Logs ending with .log.json aren't visible at all.
It also contradicts another recent article that states that file names must end in .log and its contents are treated as plain text.
As far as I can tell Google uses fluentd to index the log files into the Log Viewer. In the GitHub repository I cannot find any evidence that .log.json files are being indexed.
Does anyone know how to get this working? Or is the documentation out-of-date and has this feature been removed for some reason?
Here is one way to generate JSON logs for the Managed VMs logviewer:
The desired JSON format
The goal is to create a single line JSON object for each log line containing:
{
"message": "Error occurred!.",
"severity": "ERROR",
"timestamp": {
"seconds": 1437712034000,
"nanos": 905
}
}
(information sourced from Google: https://code.google.com/p/googleappengine/issues/detail?id=11678#c5)
Using python-json-logger
See: https://github.com/madzak/python-json-logger
def get_timestamp_dict(when=None):
"""Converts a datetime.datetime to integer milliseconds since the epoch.
Requires special handling to preserve microseconds.
Args:
when:
A datetime.datetime instance. If None, the timestamp for 'now'
will be used.
Returns:
Integer time since the epoch in milliseconds. If the supplied 'when' is
None, the return value will be None.
"""
if when is None:
when = datetime.datetime.utcnow()
ms_since_epoch = float(time.mktime(when.utctimetuple()) * 1000.0)
return {
'seconds': int(ms_since_epoch),
'nanos': int(when.microsecond / 1000.0),
}
def setup_json_logger(suffix=''):
try:
from pythonjsonlogger import jsonlogger
class GoogleJsonFormatter(jsonlogger.JsonFormatter):
FORMAT_STRING = "{message}"
def add_fields(self, log_record, record, message_dict):
super(GoogleJsonFormatter, self).add_fields(log_record,
record,
message_dict)
log_record['severity'] = record.levelname
log_record['timestamp'] = get_timestamp_dict()
log_record['message'] = self.FORMAT_STRING.format(
message=record.message,
filename=record.filename,
)
formatter = GoogleJsonFormatter()
log_path = '/var/log/app_engine/custom_logs/worker'+suffix+'.log.json'
make_sure_path_exists(log_path)
file_handler = logging.FileHandler(log_path)
file_handler.setFormatter(formatter)
logging.getLogger().addHandler(file_handler)
except OSError:
logging.warn("Custom log path not found for production logging")
except ImportError:
logging.warn("JSON Formatting not available")
To use, simply call setup_json_logger - you may also want to change the name of worker for your log.
I am currently working on a NodeJS app running on a managed VM and I am also trying to get my logs to be printed on the Google Developper Console. I created my log files in the ‘/var/log/app_engine’ directory as described in the documentation. Unfortunately this doesn’t seem to be working for me, even for the ‘.log’ files.
Could you describe where your logs are created ? Also, is your managed VM configured as "Managed by Google" or "Managed by User" ? Thanks!

I am getting 'ZZ' as country code when using pytz

I am using App engine, and I'm trying to get the time zone from the request.
However when on local host it always seems to return 'ZZ' as the country code which is not a country in pytz library.
This code:
country = self.request.headers['X-Appengine-Country']
logging.info(country)
tz = pytz.country_timezones(country)
produces this error:
return self.data[key.upper()]
KeyError: 'ZZ'
many thanks for your help
'ZZ' is often used to denote 'Unknown or unspecified country'
There is also a numeric version of the two letter code, calculated as 1070+30a+b, where a and b are the two letters of the code converted by A=1, B=2, etc. So AA=1101, AB=1102, BA=1131, and ZZ=1876.
I suggest that you use the correct case for the Request Header names. For e.g. X-AppEngine-Country
However, in the local development environment - I do not think the Location features will be supported i.e. you will not get the correct values. These should work only on the deployment environment. The Location is most likely provided by a Google Service that is internal to the Google Network and not exposed in the Local Development Environment.
Try to deploy your code to the live environment and check the values.

Resources