# README
go-common
-
Monitoring common.InitMonitoring(svcName, monitorCfg).
- Traces: otel http sink, gcp cloud trace
-
Debugging
- go tool pprof
spanner
setup local spanner
- requires gcloud (install)
snap
is not supported, uninstall and use link above!
- requires gcloud configuration
emulator
- requires spanner emulator component
Setting up emulator
config:
# Setup gcloud configuration
gcloud config configurations create --activate emulator
gcloud config set auth/disable_credentials true
gcloud config set project lingio-test
gcloud config set api_endpoint_overrides/spanner http://localhost:9020/
Installing the local spanner emulator:
gcloud components update
# Install as needed when prompted.
# If gcloud is installed via google-cloud-cli, ensure apt install command starts with google-cloud-cli instead of google-cloud-sdk
gcloud emulators spanner start
Finally, copy staging database to local emulator.
cd ~/my-service/
bash ~/go-common/script/setup-spanner-emulator.sh gcp-project-id spanner-instance-id database-name
There are certain limitations.
spanner-tools
Some useful commands that wrench
and spanner-cli
does not cover.
Especially, copying data from staging to local emulator is much faster than with spanner-cli
.
This program is installed by setup-spanner-emulator.sh
go install github.com/lingio/go-common/script/spanner-tools@latest
spanner-tools -h
storagegen
go install github.com/lingio/go-common/storagegen@latest
storagegen path/to/service/storage/spec.json
spec.json:
{
"serviceName": "person-service",
"buckets": [
{
"typeName": "People", // final type name: {typeName}Store
"dbTypeName": "DbPerson", // stored and returned type: models.{dbTypeName}
"bucketName": "people", // object store bucket name
"version": "v1", // change this if the stored data structure is changed
"getAll": false, // enable to generate code for listing all objects
"filenameFormat": "%s.json" // fmt.Sprintf format, must have exactly one %s (ID)
"secondaryIndexes": [ // generate additional Get methods
// GetByPhone, builds index on models.{dbTypeName}.Phone
{ "key": "Phone", "type": "unique" },
// GetByEmail, builds index on *models.{dbTypeName}.Email if it not nil
{ "keys": [{ "key": "Email", "optional": true }], "type": "unique" },
// GetByPartnerAndEmail, builds a compound index on models.{dbTypeName}.Partner and *models.{dbTypeName}.Email if it not nil
{ "keys": [{ "key": "Partner" }, { "key": "Email", "optional": true }], "type": "unique", "name": "PartnerAndEmail" },
// GetAllByPartnerAndStudentGroup
{
"keys": [
{ "key": "Partner" },
{ "key": "Student", "optional": true, "exclFromIndex": true },
{ "key": "Student.GroupID", "param": "groupID" }
],
"type": "set",
"name": "PartnerAndStudentGroup"
},
// GetAllByPartner, builds index on models.{dbTypeName}.Partner
{ "key": "Partner", "type": "set"}
],
// directstore.tmpl: encrypted object store
// cachedstore.tmpl: cache + encrypted object store
// blobstore.tmpl: directstore for []byte data
"template": "cachedstore.tmpl",
"config": {
// Defaults to "application/json". Will be applied on object Put.
"contentType": "application/json",
// Defaults to "". Will be applied on object Put.
"contentDisposition": ""
}
}
]
}
scripts
script/objcopy
: read/write objects from/to bucket from one s3 endpointMINIO_SECRET=xyz go run ./script/objcopy --from=path/to/{stage,local,local-stage}.json --bucket=xyz
script/encrypt
: encrypt or decrypt plaintext objects on stdinENCRYPTION_KEY=256bitkey go run ./script/encrypt
script/fromfile
: read filenames from stdin and write object to stdoutfind ./dir -not -type d | go run ./script/fromfile
script/tofile
: read objects from stdin and write files... go run ./script/objcopy | go run ./script/tofile -root=./dir
script/objify
: likefromfile
but reads raw json objectscat data.jsonl | go run ./script/objify
Write plaintext objects to disk from an encrypted object storage
# assuming encrypted bucket
$ MINIO_SECRET=minioadmin go run ./script/objcopy --from=../service/config/local-stage.json --bucket=people | \
ENCRYPTION_KEY=256bit-key go run ./script/encrypt --decrypt | \
go run ./script/tofile --root=./files --rename="people-data-{KEY}{EXT}"
Write encrypted objects to an encrypted object storage from disk
# assuming encrypted bucket
$ find ../files -maxdepth 1 -not -type d | gp run ./script/fromfile | \
ENCRYPTION_KEY=256bit-key go run ./script/encrypt | \
MINIO_SECRET=minioadmin go run ./script/objcopy --to=../service/config/local-stage.json --bucket=people
# Functions
No description provided by the author
AuthTokenFrom extracts the embedded JWT.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
DecodeSpannerStructFields copies all visible fields from source to target by struct field name.
EncodeSpannerStructFields copies all visible fields from source to target by struct field name.
Errorf returns a common lingio error wrapping the provided error.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
LogAuditEvent outputs the provided app context.
No description provided by the author
NewBucketBrowser exposes a set of storage interfaces over a HTTP API using reflection.
No description provided by the author
No description provided by the author
NewEncryptedStore initializes a lingio store with secure v2 crypto.
No description provided by the author
No description provided by the author
NewInsecureEncryptedStore initializes a lingio store with insecure v1 crypto.
NewObjectStore attempts to initialize a new bucket if it does not already exist.
NewRedisCache returns an initialized redis cache using name and version.
No description provided by the author
ProjectDecoded projects struct of type I to struct of type T using [DecodeSpannerStructFields].
ProjectIdentity is a dummy projection.
No description provided by the author
RegisterRedisOnConnectHook registers a func to be called whenever the redis client establishes a new connection to the redis server.
RequestIDFromContext extracts an embedded request id.
No description provided by the author
RespondError is deprecated.
No description provided by the author
No description provided by the author
SetMemoryLimitFromCgroup autodetects current cgroup memory.max and provides the go runtime with a soft memory limit (GOMEMLIMIT) computed as f times the cgroup value.
No description provided by the author
SetupRedisClient will attempt to 1) create a failover redis client by looking up sentinel addrs using the provided service DNS, or 2) attempt to create a simple redis client using the provided simpleAddr.
Shuffle calls swap len-1 times to swap index i with j.
No description provided by the author
SpannerQueryTyped returns all rows from query, deserialized to struct T.
SpannerQueryTypedAndDecode returns all rows from query, deserialized to struct I and then decoded into struct T using [DecodeSpannerStructField].
SpannerReadProjected returns projection `T -> P` of all rows in iterator.
SpannerReadTyped returns all rows in keySet from primary index, deserialized to struct T.
SpannerReadTypedAndDecode returns all rows in keySet from the primary index, deserialized to struct I and then decoded into struct T using [DecodeSpannerStructFields].
SpannerReadTypedAndDecodeUsingIndex is identical to [SpannerReadTypedAndDecode] but uses the provided index.
SpannerReadTypedAndDecodeWithOptions returns all rows in keySet from the primary index, deserialized to struct I and then decoded into struct T using [DecodeSpannerStructFields].
SpannerReadTypedUsingIndex is identical to [SpannerReadTyped] but uses the provided index.
SpannerReadTypedWithOptions returns all rows in keySet from primary index, deserialized to struct T.
SpannerStructFieldNames returns a list with names of all struct fields.
StatusProbeServer starts a http server on 0.0.0.0:port with the specified probes.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
UserIDFrom extracts an embedded userID from WithUserID.
WithAction returns a copy of the passed context with the specified action.
WithBucket returns a copy of the passed context with the specified bucket name.
WithObject returns a copy of the passed context with the object ID.
No description provided by the author
# Constants
No description provided by the author
No description provided by the author
# Variables
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
ErrBucketDoesNotExist is a proxy for detecting this particular error case in calling code.
No description provided by the author
No description provided by the author
# Structs
BucketBrowser s.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
EncryptedStore.
No description provided by the author
Error describes a traced HTTP error message with contextual details.
No description provided by the author
No description provided by the author
No description provided by the author
MinioConfig describes the required fields to setup a s3 minio client.
No description provided by the author
ObjectInfo.
No description provided by the author
ObjectStore implements the Lingio CRUD database interface on top of minio's object storage engine.
No description provided by the author
RedisCache is a named and versioned cache for a specific collections.
RedisConfig describes connectivity options for setting up a redis client using the included SetupRedisClient func in this pkg.
RedisSetupErr wraps an underlying error that occured during cache setup.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
# Interfaces
No description provided by the author
LingioStore is a simple file-based CRUD database interface.
StatusProbe describes a simple interface for querying service status.
# Type aliases
AtomicBool.
Backoff returns the time to wait for request retry attempt.
No description provided by the author
No description provided by the author
No description provided by the author
ShouldRetry returns whether a request can be retried:
err = request error attempt = 0-based retry counter.