Server Error 500 when deploying Go backend with Gorm, using CloudSQL and Google App Engine - go

I'm trying to deploy a Go backend on Google App Engine, connecting to CloudSQL. Deploy magic is working, but when I try to call the API, I get a 500 status:
Error: Server Error
The server encountered an error and could not complete your request.
Please try again in 30 seconds.
When running gcloud app logs tail -s default, I have:
2020/06/07 21:39:26 server.go:52: dial unix /cloudsql/: connect: is a directory
var dbURI string
dbURI = fmt.Sprintf("%s:%s#unix(/cloudsql/%s)/%s", dbUser, dbPwd, dbHost, dbName)
// Open database connection
db, err := gorm.Open(
"mysql",
dbURI,
)
if err != nil {
log.Fatal(err) <-- line 52
}
My app.yaml is setup correctly (I think..):
env_variables:
CLOUDSQL_CONNECTION_NAME: 'XXXXX:europe-west1:XXXXXX'
DB_USER: 'root'
DB_PASS: 'XXXXX'
DB_NAME: 'XXXXX'
Any help would be appreciated :)

I was indeed not using the right ENV variable.. Thank you for pointing that out #Muffin Top

Related

How to write a go connection string for pgx.pool to a remote RDS?

I have no trouble connecting go pgxpool to a postgresql database in a docker container but can't figure out how to write a connection URL string for a linode postgresql RDS. Specifically, what is the first part of the URL "postgres://"? I can't find any example for a connection URL other than a local db and no code examples for a DSN connection.
Can somebody please help me out with either a connection URL or DSN for these details?
Here is my current connection string which returns "host is invalid". ssl_mode is also invalid.
config, err := pgxpool.ParseConfig("user=linpostgres, password=secret, host=lin-9930-2356-pgsql-primary.servers.linodedb.net, port=5432 dbname=mydb, pool_max_conns=10")
This psq connect string times out: psql --username=linpostgres --host=lin-9930-2356-pgsql-primary.servers.linodedb.net port=5432 --password
You can check the code official GitHub repository code here: link
// See Config for definitions of these arguments.
//
// # Example DSN
// user=jack password=secret host=pg.example.com port=5432 dbname=mydb sslmode=verify-ca pool_max_conns=10
//
// # Example URL
// postgres://jack:secret#pg.example.com:5432/mydb?sslmode=verify-ca&pool_max_conns=10
so your connection string should be
postgres://jack:secret#pg.example.com:5432/mydb?sslmode=verify-ca&pool_max_conns=10
hope this helps

gomobile build, the Paho mqtt client cannot connect to mqtt broker in APK

I am working on a project where I need to use gomobile tool to create an Android app.
The sample code I have in Go is as below
var broker = "127.0.0.1"
//var broker = "broker.mqttdashboard.com"
var port = 1883
opts := mqtt.NewClientOptions()
opts.AddBroker(fmt.Sprintf("tcp://%s:%d", broker, port))
opts.SetClientID("go_mqtt_client")
opts.SetConnectionLostHandler(connectLostHandler) // define what to do when connection is lost
client := mqtt.NewClient(opts)
tokenClient := client.Connect()
if tokenClient.Wait() && tokenClient.Error() != nil {
panic(tokenClient.Error())
}
...
When I bind this code using "gomobile bind", generating the Golang plugin and calling them inside the android project there is no issue.
Connections is satisfied and I can verify the local mqtt broker (mosquitto) and the mqtt client app are communicating as well.
But when I generate the APK file using "gomobile build -target=android", the connect function generates and error.
To be able to test the logs i used a public broker instead of the local mqtt broker. I replaced the
var broker = "127.0.0.1"
by the HiveMQ public broker address (I have already validated the public broker functionality)
var broker = "broker.mqttdashboard.com"
It seems like there is an issue with connecting from mqtt client app to mqtt broker. Here is the exact error message I found in logs:
E/Go: panic: network Error : dial tcp: lookup
broker.mqttdashboard.com: No address associated with hostname
goroutine 11 [running]: E/GoLog: panic: network Error : dial tcp: lookup broker.mqttdashboard.com: No address associated with hostname
E/Go: main.starting()
This is generated by "panic(tokenClient.Error())" part in my code.
Any idea why the connection is not settled using "gomobile build", while it is working when I use "gomobile bind" ?
Here is how I could fix the issue.
I added the AndoridManifest.xml file to the same directory that the main go package is.
Added the following line in between the manifest tags (<manifest> )
<uses-permission android:name="android.permission.INTERNET">

telegraf output to Elasticsearch: "health check timeout: no Elasticsearch node available"

I'm having trouble connecting to an Elasticsearch instance with a Telegraf output plugin.
I created an Elasticsearch setup via the Elasticsearch service. I created a user and password (connected to a role) in Kibana for it.
Then I setup a Telegraf output for it:
[[outputs.elasticsearch]]
urls = [ "https://hostname:port" ] # required.
timeout = "5s"
enable_sniffer = false
health_check_interval = "10s"
## HTTP basic authentication details.
username = "my_username"
password = "my_password"
index_name = "device_logs" # required.
insecure_skip_verify = true
manage_template = true
template_name = "telegraf"
overwrite_template = false
But when I try to start Telegraf with this, it just gives the error,
[agent] Failed to connect to [outputs.elasticsearch], retrying in 15s, error was 'health check timeout: no Elasticsearch node available'
The connect fail seems to originate deep in the bowels of golang's net/http library, and I don't know how to get some more useful output at this point.
Things I've tried:
Thing #1: I tested cURL:
curl -u my_username:my_password -X POST "https://hostname:port/device_logs/_doc" -H 'Content-Type: application/json' -d'
{
"name": "John Doe"
}'
This works fine.
Thing #2: I created a simple Go program to connect to elasticsearch from Go:
package main
import (
"log"
"time"
"gopkg.in/olivere/elastic.v3"
)
func main() {
// configure connection to ES
client, err := elastic.NewClient(elastic.SetURL("https://hostname:port"))
if err != nil {
panic(err)
}
log.Printf("client.running? %v",client.IsRunning())
if ! client.IsRunning() {
panic("Could not make connection, not running")
}
}
.. and it hits the first panic with the same "no Elasticsearch node available".
Thing #3: I tried running gdb on that Go program to debug into it.
It jumps down to assembly as soon as I call NewClient, so I can't really learn what is happening in the bowels of net/http.
I've never used Go before, so I'm hoping to avoid hours of learning Go, spelunking, and debugging to get around what hopefully is a simple issue here.
Any ideas on how to get more info here or why this is failing? Are there build or runtime flags for Go that I can use? gdb-with-Go debugging tips so I can step down into the Go library code? Elasticsearch client know-how?
To answer my own question, the problem here turned out to be the roles permissions. The Telegraf output plugin for Elasticsearch needs both the monitor and the manage_index_templates permissions to be enabled, or else it'll fail to connect to the Elasticsearch server without printing any information about why.
BTW: to build golang code and be able to debug into the libraries it calls:
go build -gcflags=all="-N -l"

Client timeout exceeded while awaiting headers

I got below error, I am using go v1.10.4 linux/amd64.
I am not behind any firewall or whatsoever. New Relic in java server (same network segment) that we have runs fine.
We have tried:
Increasing the timeout to 60 seconds
Use http2 in the server
Using Postman return 503 with response:
{"exception":{"message":"Server Error","error_type":"RuntimeError"}}
troubleshooting with ./nrdiag says “No Issues Found”
Below is our code:
config := newrelic.NewConfig(os.Getenv("NEW_RELIC_APP_NAME"), os.Getenv("NEW_RELIC_KEY"))
config.Logger = newrelic.NewDebugLogger(os.Stdout)
app, err := newrelic.NewApplication(config)
if err != nil {
fmt.Println("Failed to create newrelic application", err)
os.Exit(1)
}
.................
httpListener, err := net.Listen("tcp", *httpAddr)
if err != nil {
oldlog.Print("Error: ", err)
logger.Log("transport", "HTTP", "during", "Listen", "err", err)
os.Exit(1)
}
g.Add(func() error {
logger.Log("transport", "HTTP", "addr", *httpAddr)
return http.Serve(httpListener, nrgorilla.InstrumentRoutes(httpHandler, app))
}, func(error) {
httpListener.Close()
})
}
However this what we got,note some_key was removed:
(28422) 2019/07/29 18:08:50.058559 {"level":"warn","msg":"application connect failure","context":{"error":"Post https://collector-001.eu01.nr-data.net/agent_listener/invoke_raw_method?license_key=some_key\u0026marshal_format=json\u0026method=connect\u0026protocol_version=17: net/http: request canceled (Client.Timeout exceeded while awaiting headers)"}}
I think it is due to DNS network timeout.
You can easily test this out by using the following steps (in Ubuntu)
Select the IPv4 Settings tab.
Disable the “Automatic” toggle switch and enter the DNS resolvers' IP addresses, separated by a comma. We’ll use the Google DNS nameservers:
8.8.8.8,8.8.4.4
If it works, then you may be able to reset the DNS to "Automatic"
On Windows OS, Running Linux Containers with WSL2, i followed the following steps,
Ran the command docker logout
Ran the command, docker network prune, so as to remove all the preconfigured settings of the network.
From Docker Settings, Enabled the DNS server configuration with 8.8.8.8
Restarted the Docker
Now executed login command with registry to login, docker login {registry}

How to connect to a Gremlin Websocket in Go?

I'm trying to connect to Gremlin which should be running on port 8182 ([INFO] GremlinServer$1 - Channel started at port 8182)
When I'm connecting to: ws://127.0.0.1:8182 I'm getting the response:
2017/11/03 17:20:04 ERROR: database with the name 'gremlin' gave an error when connecting: websocket: bad handshake.
The Gremlin server responds with:
[WARN] HttpGremlinEndpointHandler - Invalid request - responding with 400 Bad Request and no gremlin script supplied
I'm using Gorilla Websocket in Go to connect:
gremlinGrpcAddress := fmt.Sprintf("ws://%s:%d/", f.config.Host, f.config.Port)
var dialer *websocket.Dialer
clientConn, _, err := dialer.Dial(gremlinGrpcAddress, nil)
if err != nil {
return err
}
f.client = clientConn
UPDATE:
Connecting to echo.websocket.org works, so somehow it is something in the Gremlin server.
The answer lies in the config YAML file.
What is needed is the correct channelizer.
GOOD:
channelizer: org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer
Connect to ws://localhost:8182/gremlin instead of ws://localhost:8182. There are several references to it in the Apache TinkerPop documentation and the go-gremlin README.

Resources