Просмотр исходного кода

Merge pull request #226 from enidgjoleka/use-application-name-when-establishing-a-connection

Use application name when establishing a connection
Sergey Prokhorov 5 лет назад
Родитель
Сommit
d8ca6d4d94
4 измененных файлов с 28 добавлено и 3 удалено
  1. 3 0
      README.md
  2. 7 1
      src/commands/epgsql_cmd_connect.erl
  3. 5 2
      src/epgsql.erl
  4. 13 0
      test/epgsql_SUITE.erl

+ 3 - 0
README.md

@@ -112,6 +112,9 @@ Only `host` and `username` are mandatory, but most likely you would need `databa
    Default is `[null, undefined]`, i.e. encode `null` or `undefined` in parameters as `NULL`
    and decode `NULL`s as atom `null`.
 - `replication` see [Streaming replication protocol](#streaming-replication-protocol)
+- `application_name` is an optional string parameter. It is usually set by an application upon
+   connection to the server. The name will be displayed in the `pg_stat_activity`
+   view and included in CSV log entries.
 
 Options may be passed as proplist or as map with the same key names.
 

+ 7 - 1
src/commands/epgsql_cmd_connect.erl

@@ -89,7 +89,13 @@ client_handshake(Sock, PgSock, #connect{opts = #{username := Username} = Opts} =
                          epgsql_sock:init_replication_state(PgSock1)};
                     _ -> {Opts3, PgSock1}
                 end,
-            ok = epgsql_sock:send(PgSock2, [<<196608:?int32>>, Opts4, 0]),
+            Opts5 = case Opts of
+                        #{application_name := ApplicationName}  ->
+                            [Opts3 | ["application_name", 0, ApplicationName, 0]];
+                        _ ->
+                            Opts4
+                    end,
+            ok = epgsql_sock:send(PgSock2, [<<196608:?int32>>, Opts5, 0]),
             PgSock3 = case Opts of
                           #{async := Async} ->
                               epgsql_sock:set_attr(async, Async, PgSock2);

+ 5 - 2
src/epgsql.erl

@@ -62,7 +62,8 @@
     {async,    Receiver   :: pid() | atom()}       | % process to receive LISTEN/NOTIFY msgs
     {codecs,   Codecs     :: [{epgsql_codec:codec_mod(), any()}]} |
     {nulls,    Nulls      :: [any(), ...]} |    % terms to be used as NULL
-    {replication, Replication :: string()}. % Pass "database" to connect in replication mode
+    {replication, Replication :: string()} | % Pass "database" to connect in replication mode
+    {application_name, ApplicationName :: string()}.
 
 -type connect_opts() ::
         [connect_option()]
@@ -77,7 +78,9 @@
           async => pid() | atom(),
           codecs => [{epgsql_codec:codec_mod(), any()}],
           nulls => [any(), ...],
-          replication => string()}.
+          replication => string(),
+          application_name => string()
+          }.
 
 -type connect_error() :: epgsql_cmd_connect:connect_error().
 -type query_error() :: #error{}.              % Error report generated by server

+ 13 - 0
test/epgsql_SUITE.erl

@@ -34,6 +34,7 @@ groups() ->
     Groups = [
         {connect, [parrallel], [
             connect,
+            connect_with_application_name,
             connect_to_db,
             connect_as,
             connect_with_cleartext,
@@ -179,6 +180,18 @@ uuid_to_bin_string(<<U0:32, U1:16, U2:16, U3:16, U4:48>>) ->
 connect(Config) ->
     epgsql_ct:connect_only(Config, []).
 
+connect_with_application_name(Config) ->
+    Module = ?config(module, Config),
+    Fun = fun(C) ->
+              Query = "select application_name from pg_stat_activity",
+              {ok, _Columns, Rows} = Module:equery(C, Query),
+              ?assert(lists:member({<<"app_test">>}, Rows))
+          end,
+    epgsql_ct:with_connection(Config,
+                              Fun,
+                              "epgsql_test",
+                              [{application_name, "app_test"}]).
+
 connect_to_db(Connect) ->
     epgsql_ct:connect_only(Connect, [{database, "epgsql_test_db1"}]).