|
| 1 | +package main |
| 2 | + |
| 3 | +import ( |
| 4 | + "database/sql" |
| 5 | + "fmt" |
| 6 | + "log" |
| 7 | + "net/url" |
| 8 | + "time" |
| 9 | + |
| 10 | + _ "github.com/go-sql-driver/mysql" |
| 11 | +) |
| 12 | + |
| 13 | +const ( |
| 14 | + MySQLUsername = "root" |
| 15 | + MySQLPassword = "secret" |
| 16 | + MySQLHostname = "127.0.0.1" |
| 17 | + MySQLPort = 3306 |
| 18 | + MySQLDatabase = "dummy" |
| 19 | + ConnectionAttributeName = "program_name" |
| 20 | + ConnectionName = "currency-conversion-app" |
| 21 | +) |
| 22 | + |
| 23 | +func main() { |
| 24 | + // Doing all the magic: Setting a proper connection/application name. |
| 25 | + // |
| 26 | + // Connection attributes are key-value pairs that application programs can pass to the server at connect time. |
| 27 | + // This property can be added to the connection string. |
| 28 | + // |
| 29 | + // The application name will be maintained in the `session_connect_attrs` table of your MySQL-Server. |
| 30 | + // |
| 31 | + // MySQL docs: |
| 32 | + // - Performance Schema Connection Attribute Tables: https://dev.mysql.com/doc/refman/8.0/en/performance-schema-connection-attribute-tables.html |
| 33 | + // - Connection Attribute Limits: https://dev.mysql.com/doc/refman/8.0/en/performance-schema-connection-attribute-tables.html#performance-schema-connection-attribute-limits |
| 34 | + |
| 35 | + dsn := fmt.Sprintf("%s@tcp(%s:%d)/%s?connectionAttributes=%s:%s", url.UserPassword(MySQLUsername, MySQLPassword), MySQLHostname, MySQLPort, MySQLDatabase, ConnectionAttributeName, ConnectionName) |
| 36 | + |
| 37 | + // Building the connection |
| 38 | + log.Printf("Connecting to MySQL on %s\n", dsn) |
| 39 | + client, err := sql.Open("mysql", dsn) |
| 40 | + if err != nil { |
| 41 | + panic(err) |
| 42 | + } |
| 43 | + defer func() { |
| 44 | + if err = client.Close(); err != nil { |
| 45 | + panic(err) |
| 46 | + } |
| 47 | + }() |
| 48 | + |
| 49 | + // Dummy values for demo purpose |
| 50 | + client.SetConnMaxLifetime(time.Minute * 3) |
| 51 | + client.SetMaxOpenConns(10) |
| 52 | + client.SetMaxIdleConns(10) |
| 53 | + |
| 54 | + // Establish the connection, because depending on the DB driver, we might only |
| 55 | + // validate the credentials, but don't built up a connection. |
| 56 | + err = client.Ping() |
| 57 | + if err != nil { |
| 58 | + panic(err) |
| 59 | + } |
| 60 | + log.Printf("Connecting to MySQL on %s ... Successful\n", dsn) |
| 61 | + |
| 62 | + log.Println("") |
| 63 | + log.Println("Keeping the connection open ...") |
| 64 | + log.Println("You can connect to the MySQL database and execute the query:") |
| 65 | + log.Println(" SELECT") |
| 66 | + log.Println(" session_connect_attrs.ATTR_VALUE AS program_name,") |
| 67 | + log.Println(" processlist.*") |
| 68 | + log.Println(" FROM information_schema.processlist") |
| 69 | + log.Println(" LEFT JOIN performance_schema.session_connect_attrs ON (") |
| 70 | + log.Println(" processlist.ID = session_connect_attrs.PROCESSLIST_ID") |
| 71 | + log.Println(" AND session_connect_attrs.ATTR_NAME = \"program_name\"") |
| 72 | + log.Println(" )") |
| 73 | + log.Println("Hit CTRL + C or cancel the process to stop.") |
| 74 | + log.Println("") |
| 75 | + |
| 76 | + // Just looping to keep the process running. |
| 77 | + // In detail we do not keep the connection active, but rely on the standard timeout. |
| 78 | + // This way we provide time for the user to check the connection name behaviour. |
| 79 | + for { |
| 80 | + err = client.Ping() |
| 81 | + if err != nil { |
| 82 | + panic(err) |
| 83 | + } |
| 84 | + time.Sleep(5 * time.Second) |
| 85 | + } |
| 86 | +} |
0 commit comments