Repository: gofr-dev/gofr

Issue:
Add default metrics in SurrealDB
Current implementation does not have in-built metrics .... We must add them.

Hints from issue comments:

Solution patch:
diff --git a/docs/datasources/getting-started/page.md b/docs/datasources/getting-started/page.md
index 20412bb0..cdb531d5 100644
--- a/docs/datasources/getting-started/page.md
+++ b/docs/datasources/getting-started/page.md
@@ -148,7 +148,7 @@ as unnecessary database drivers are not being compiled and added to the build.
 -  SurrealDB
 - ✅
 - ✅
--
+- ✅
 - ✅
 - ✅
 ---
diff --git a/pkg/gofr/datasource/README.md b/pkg/gofr/datasource/README.md
index ce5c18b0..941a61e9 100644
--- a/pkg/gofr/datasource/README.md
+++ b/pkg/gofr/datasource/README.md
@@ -85,7 +85,7 @@ Therefore, GoFr utilizes a pluggable approach for new datasources by separating
 | DGraph           |      ✅       |  ✅   |    ✅    |   ✅    |           |
 | Azure Event Hubs |              |  ✅   |    ✅    |        |     ✅     |
 | OpenTSDB         |      ✅       |  ✅   |         |   ✅    |     ✅     |
-| SurrealDB        |      ✅       |  ✅   |         |   ✅    |     ✅     |
+| SurrealDB        |      ✅       |  ✅   |    ✅    |   ✅    |     ✅     |
 | ArangoDB         |      ✅       |  ✅   |    ✅    |   ✅    |     ✅     |
 | NATS-KV          |      ✅       |  ✅   |    ✅    |   ✅    |     ✅     |
 | ScyllaDB         |      ✅       |  ✅   |    ✅    |   ✅    |           |
\ No newline at end of file
diff --git a/pkg/gofr/datasource/surrealdb/surrealdb.go b/pkg/gofr/datasource/surrealdb/surrealdb.go
index 05b9db96..83237415 100644
--- a/pkg/gofr/datasource/surrealdb/surrealdb.go
+++ b/pkg/gofr/datasource/surrealdb/surrealdb.go
@@ -131,6 +131,11 @@ func newDB(connectionURL string) (con connection.Connection, err error) {
 func (c *Client) Connect() {
 	c.logger.Debugf("connecting to SurrealDB at %v:%v to database %v", c.config.Host, c.config.Port, c.config.Database)
 
+	surrealDBBuckets := []float64{.05, .075, .1, .125, .15, .2, .3, .5, .75, 1, 2, 3, 4, 5, 7.5, 10}
+
+	c.metrics.NewHistogram("app_surrealdb_stats", "Response time of SurrealDB operations in microseconds.", surrealDBBuckets...)
+	c.metrics.NewGauge("app_surrealdb_open_connections", "Number of open SurrealDB connections.")
+
 	endpoint := c.buildEndpoint()
 	err := c.connectToDatabase(endpoint)
 
@@ -658,6 +663,18 @@ func (c *Client) sendOperationStats(ql *QueryLog, startTime time.Time) {
 	ql.Namespace = c.config.Namespace
 	ql.Database = c.config.Database
 
+	c.metrics.RecordHistogram(context.Background(), "app_surrealdb_stats", float64(duration),
+		"namespace", ql.Namespace,
+		"database", ql.Database,
+		"operation", ql.OperationName)
+
+	var nbConnection float64
+	if c.db != nil {
+		nbConnection = 1
+	}
+
+	c.metrics.SetGauge("app_surrealdb_open_connections", nbConnection)
+
 	if ql.Span == nil {
 		return
 	}



Test patch:
diff --git a/pkg/gofr/datasource/surrealdb/surrealdb_test.go b/pkg/gofr/datasource/surrealdb/surrealdb_test.go
index 0310328b..d1ff849d 100644
--- a/pkg/gofr/datasource/surrealdb/surrealdb_test.go
+++ b/pkg/gofr/datasource/surrealdb/surrealdb_test.go
@@ -160,6 +160,8 @@ func Test_Query(t *testing.T) {
 
 		mockLogger.EXPECT().Debug(gomock.Any()).AnyTimes()
 		mockLogger.EXPECT().Errorf(gomock.Any(), gomock.Any()).AnyTimes()
+		mockMetrics.EXPECT().RecordHistogram(gomock.Any(), "app_surrealdb_stats", gomock.Any(), gomock.Any())
+		mockMetrics.EXPECT().SetGauge("app_surrealdb_open_connections", float64(1))
 
 		results, err := client.Query(ctx, query, nil)
 		require.NoError(t, err)
@@ -181,6 +183,8 @@ func Test_Query(t *testing.T) {
 			Return(errInvalidQuery)
 
 		mockLogger.EXPECT().Debug(gomock.Any()).AnyTimes()
+		mockMetrics.EXPECT().RecordHistogram(gomock.Any(), "app_surrealdb_stats", gomock.Any(), gomock.Any())
+		mockMetrics.EXPECT().SetGauge("app_surrealdb_open_connections", float64(1))
 
 		results, err := client.Query(ctx, query, nil)
 		require.Error(t, err)
@@ -217,6 +221,8 @@ func Test_Create(t *testing.T) {
 		}
 
 		mockLogger.EXPECT().Debug(gomock.Any()).AnyTimes()
+		mockMetrics.EXPECT().RecordHistogram(gomock.Any(), "app_surrealdb_stats", gomock.Any(), gomock.Any())
+		mockMetrics.EXPECT().SetGauge("app_surrealdb_open_connections", float64(1))
 
 		mockConn.EXPECT().
 			Send(gomock.Any(), "create", "users", data).
@@ -238,6 +244,8 @@ func Test_Create(t *testing.T) {
 		mockConn.EXPECT().
 			Send(gomock.Any(), "create", "users", data).
 			Return(errorDatabase)
+		mockMetrics.EXPECT().RecordHistogram(gomock.Any(), "app_surrealdb_stats", gomock.Any(), gomock.Any())
+		mockMetrics.EXPECT().SetGauge("app_surrealdb_open_connections", float64(1))
 
 		result, err := client.Create(ctx, "users", data)
 		require.Error(t, err)
@@ -285,6 +293,8 @@ func Test_Update(t *testing.T) {
 		}
 
 		mockLogger.EXPECT().Debug(gomock.Any()).AnyTimes()
+		mockMetrics.EXPECT().RecordHistogram(gomock.Any(), "app_surrealdb_stats", gomock.Any(), gomock.Any())
+		mockMetrics.EXPECT().SetGauge("app_surrealdb_open_connections", float64(1))
 
 		mockConn.EXPECT().
 			Send(gomock.Any(), "query", expectedQuery, data).
@@ -329,6 +339,7 @@ func Test_Select(t *testing.T) {
 	client := New(&Config{})
 	client.UseLogger(mockLogger)
 	client.UseMetrics(mockMetrics)
+	client.UseTracer(otel.GetTracerProvider().Tracer("gofr-surrealdb"))
 	client.db = mockConn
 
 	t.Run("successful select", func(t *testing.T) {
@@ -346,6 +357,8 @@ func Test_Select(t *testing.T) {
 		}
 
 		mockLogger.EXPECT().Debug(gomock.Any()).AnyTimes()
+		mockMetrics.EXPECT().RecordHistogram(gomock.Any(), "app_surrealdb_stats", gomock.Any(), gomock.Any())
+		mockMetrics.EXPECT().SetGauge("app_surrealdb_open_connections", float64(1))
 
 		mockConn.EXPECT().
 			Send(gomock.Any(), "select", "users").
@@ -367,6 +380,8 @@ func Test_Select(t *testing.T) {
 		}
 
 		mockLogger.EXPECT().Debug(gomock.Any()).AnyTimes()
+		mockMetrics.EXPECT().RecordHistogram(gomock.Any(), "app_surrealdb_stats", gomock.Any(), gomock.Any())
+		mockMetrics.EXPECT().SetGauge("app_surrealdb_open_connections", float64(1))
 
 		mockConn.EXPECT().
 			Send(gomock.Any(), "select", "users").