Google Cloud でロギング(JavaScript編)

システムの実運用を始めると避けて通れないのがロギングです。
しっかり設計しておかないとトラブルシューティングができません。
Google の AppEngine, Cloud Functions のようなサーバーレスサービスを利用する場合 Cloud Logging をほぼ使うことになると思われますが、何をどうすればどうログが出力されるのかまとまった資料がなかったのでまとめてみました。


## Severity

Google の Cloud Logging には以下の９レベルの severity があります。
* Default
* Debug
* Info
* Notice
* Warning
* Error
* Critical
* Alert
* Emergency

![スクリーンショット 2022-11-16 21.29.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73493/2eb89ac8-208d-0097-77e6-ef560ff2e23e.png)

プログラムが標準出力、標準エラーにテキストを出力すると、Severity は Default になります。
ただし、console.log, console.error に Error オブジェクトを渡すと、Severity は Error になります。

プログラムがエラーを起こした場合（例外を一番外でキャッチしなかった時を含みます）、Severity は Error になります。

それ以外の Severity で出力したい場合は、
`@google-cloud/logging`
を使います。


## 概要

* LogName projects/${project-id}/logs/stdoutにテキストがDefault レベルで出力される
```
	process.stdout.write( 'stdout\n' )

	console.debug	( { message: 'debug'	} )
	console.info	( { message: 'info'		} )
	console.log		( { message: 'log'		} )
```

* LogName projects/${project-id}/logs/stderrにテキストがDefault レベルで出力される
```
	process.stderr.write( 'stderr\n' )
	console.warn	( { message: 'warn'		} )
	console.error	( { message: 'error'	} )
```




* LogName projects/${project-id}/logs/stdoutにError レベルで出力される(スタックトレースが出力される)

```
	console.debug	( new Error( 'debug'	) )
	console.info	( new Error( 'info'		) )
	console.log		( new Error( 'log'		) )
```


* LogName projects/${project-id}/logs/stderrにError レベルで出力される(スタックトレースが出力される)

```
	console.warn	( new Error( 'warn'		) )
	console.error	( new Error( 'error'	) )
```

## きっちりとしたログレベルをやりたかったら

### AppEngine

```
'use strict';

const log = new ( require( '@google-cloud/logging' ).Logging )().log( 'EXP-JavaScript' )
const LOG = ( severity, text ) => log.write(
	log.entry(
		{ severity }
	,	text
	)
)
const DEFAULT	= text => LOG( 'DEFAULT'	, text )
const DEBUG		= text => LOG( 'DEBUG'		, text )
const INFO		= text => LOG( 'INFO'		, text )
const NOTICE	= text => LOG( 'NOTICE'		, text )
const WARNING	= text => LOG( 'WARNING'	, text )
const ERROR		= text => LOG( 'ERROR'		, text )
const CRITICAL	= text => LOG( 'CRITICAL'	, text )
const ALERT		= text => LOG( 'ALERT'		, text )
const EMERGENCY	= text => LOG( 'EMERGENCY'	, text )

const app = require( 'express' )()

app.get(
	'/'
,	(req, res) => (

		process.stdout.write( 'stdout\n' )
	,	process.stderr.write( 'stderr\n' )

	,	console.debug	( { message: 'debug'	} )
	,	console.info	( { message: 'info'		} )
	,	console.log		( { message: 'log'		} )
	,	console.warn	( { message: 'warn'		} )
	,	console.error	( { message: 'error'	} )

	,	console.debug	( new Error( 'debug'	) )
	,	console.info	( new Error( 'info'		) )
	,	console.log		( new Error( 'log'		) )
	,	console.warn	( new Error( 'warn'		) )
	,	console.error	( new Error( 'error'	) )

	,	DEFAULT		( 'DEFAULT'		)
	,	DEBUG		( 'DEBUG'		)
	,	INFO		( 'INFO'		)
	,	NOTICE		( 'NOTICE'		)
	,	WARNING		( 'WARNING'		)
	,	ERROR		( 'ERROR'		)
	,	CRITICAL	( 'CRITICAL'	)
	,	ALERT		( 'ALERT'		)
	,	EMERGENCY	( 'EMERGENCY'	)

	,	res.status( 200 ).send( 'AppEngine, JavaScript' ).end()
	)
)

app.listen( parseInt( process.env.PORT ) )

module.exports = app

```

### Cloud Functions

```
const log = new ( require( '@google-cloud/logging' ).Logging )().log( 'EXP-JavaScript' )
const LOG = ( severity, text ) => log.write(
	log.entry(
		{ severity }
	,	text
	)
)
const DEFAULT	= text => LOG( 'DEFAULT'	, text )
const DEBUG		= text => LOG( 'DEBUG'		, text )
const INFO		= text => LOG( 'INFO'		, text )
const NOTICE	= text => LOG( 'NOTICE'		, text )
const WARNING	= text => LOG( 'WARNING'	, text )
const ERROR		= text => LOG( 'ERROR'		, text )
const CRITICAL	= text => LOG( 'CRITICAL'	, text )
const ALERT		= text => LOG( 'ALERT'		, text )
const EMERGENCY	= text => LOG( 'EMERGENCY'	, text )

exports.helloWorld = ( req, res ) => {
	process.stdout.write( 'stdout\n' )
	process.stderr.write( 'stderr\n' )

	console.debug	( { message: 'debug'	} )
	console.info	( { message: 'info'		} )
	console.log		( { message: 'log'		} )
	console.warn	( { message: 'warn'		} )
	console.error	( { message: 'error'	} )

	console.debug	( new Error( 'debug'	) )
	console.info	( new Error( 'info'		) )
	console.log		( new Error( 'log'		) )
	console.warn	( new Error( 'warn'		) )
	console.error	( new Error( 'error'	) )

	DEFAULT		( 'DEFAULT'		)
	DEBUG		( 'DEBUG'		)
	INFO		( 'INFO'		)
	NOTICE		( 'NOTICE'		)
	WARNING		( 'WARNING'		)
	ERROR		( 'ERROR'		)
	CRITICAL	( 'CRITICAL'	)
	ALERT		( 'ALERT'		)
	EMERGENCY	( 'EMERGENCY'	)

	res.status( 200 ).send( 'Cloud Functions, JavaScript' )
}
```

## Service

Google Cloud には以下の2つのServerlessサービスがあります。
* AppEngine
* Cloud Functions
両方で検証してみたところ同じでした。