Skip to content

Commit 649b500

Browse files
authored
Chore: Move all backend contribution documents to a single directory (grafana#61140)
1 parent 4de0149 commit 649b500

File tree

14 files changed

+108
-107
lines changed

14 files changed

+108
-107
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,7 @@ WORKFLOW.md @torkelo
286286
/pkg/services/thumbs/ @grafana/grafana-edge-squad
287287

288288
# Backend code docs
289-
/contribute/style-guides/backend.md @grafana/backend-platform
290-
/contribute/architecture/backend/ @grafana/backend-platform
291-
/contribute/engineering/backend/ @grafana/backend-platform
289+
/contribute/backend/ @grafana/backend-platform
292290

293291

294292
/crowdin.yml @grafana/user-essentials

contribute/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ This directory contains guides for contributors to the Grafana project.
1010

1111
The `style-guides` directory contains style guides for the Grafana software project and documentation.
1212

13-
- [Backend style guide](style-guides/backend.md) for how to style and format backend functionality and code.
13+
- [Backend style guide](backend/style-guide.md) for how to style and format backend functionality and code.
1414
- [Frontend style guide](style-guides/frontend.md) for how to style and format the user-facing functionality and code.
1515
- [Redux framework](style-guides/redux.md) for designing the Grafana redux framework.
1616
- [Themes style guide](style-guides/themes.md) for designing and updating Grafana themes.

contribute/architecture/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ Are you looking to take on contributions with bigger impact? These guides help y
44

55
Learn more about the backend architecture:
66

7-
- Part 1: [Services](backend/services.md)
8-
- Part 2: [Communication](backend/communication.md)
9-
- Part 3: [Database](backend/database.md)
7+
- Part 1: [Services](../backend/services.md)
8+
- Part 2: [Communication](../backend/communication.md)
9+
- Part 3: [Database](../backend/database.md)
1010

1111
Learn more about the frontend architecture:
1212

contribute/backend/README.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Backend
2+
3+
This document gives an overview of the directory structure, and ongoing refactorings.
4+
5+
For more information on developing for the backend:
6+
7+
- [Backend style guide](/contribute/backend/style-guide.md)
8+
- [Architecture](/contribute/architecture)
9+
10+
## Central folders of Grafana's backend
11+
12+
| folder | description |
13+
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
14+
| /pkg/api | HTTP handlers and routing. Almost all handler funcs are global which is something we would like to improve in the future. Handlers should be associated with a struct that refers to all dependencies. |
15+
| /pkg/cmd | The binaries that we build: grafana-server and grafana-cli. |
16+
| /pkg/components | A mix of third-party packages and packages we have implemented ourselves. Includes our packages that have out-grown the util package and don't naturally belong somewhere else. |
17+
| /pkg/infra | Packages in infra should be packages that are used in multiple places in Grafana without knowing anything about the Grafana domain. |
18+
| /pkg/services | Packages in services are responsible for persisting domain objects and manage the relationship between domain objects. Services should communicate with each other using DI when possible. Most of Grafana's codebase still relies on global state for this. Any new features going forward should use DI. |
19+
| /pkg/tsdb | All backend implementations of the data sources in Grafana. Used by both Grafana's frontend and alerting. |
20+
| /pkg/util | Small helper functions that are used in multiple parts of the codebase. Many functions are placed directly in the util folders which is something we want to avoid. Its better to give the util function a more descriptive package name. Ex `errutil`. |
21+
22+
## Central components of Grafana's backend
23+
24+
| package | description |
25+
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
26+
| /pkg/bus | The bus is described in more details under [Communication](/contribute/backend/communication.md) |
27+
| /pkg/models | This is where we keep our domain model. This package should not depend on any package outside standard library. It does contain some references within Grafana but that is something we should avoid going forward. |
28+
| /pkg/registry | Package for managing services. |
29+
| /pkg/services/alerting | Grafana's alerting services. The alerting engine runs in a separate goroutine and shouldn't depend on anything else within Grafana. |
30+
| /pkg/services/sqlstore | Currently where the database logic resides. |
31+
| /pkg/setting | Anything related to Grafana global configuration should be dealt with in this package. |
32+
33+
## Dependency management
34+
35+
Refer to [UPGRADING_DEPENDENCIES.md](https://github.com/grafana/grafana/blob/main/UPGRADING_DEPENDENCIES.md).
36+
37+
## Ongoing refactoring
38+
39+
These issues are not something we want to address all at once but something we will improve incrementally. Since Grafana is released at a regular schedule the preferred approach is to do this in batches. Not only is it easier to review, but it also reduces the risk of conflicts when cherry-picking fixes from main to release branches. Please try to submit changes that span multiple locations at the end of the release cycle. We prefer to wait until the end because we make fewer patch releases at the end of the release cycle, so there are fewer opportunities for complications.
40+
41+
### Global state
42+
43+
Global state makes testing and debugging software harder and it's something we want to avoid when possible. Unfortunately, there is quite a lot of global state in Grafana.
44+
45+
We want to migrate away from this by using the `inject` package to wire up all dependencies either in `pkg/cmd/grafana-server/main.go` or self-registering using `registry.RegisterService` ex https://github.com/grafana/grafana/blob/main/pkg/services/cleanup/cleanup.go#L25.
46+
47+
### Limit the use of the init() function
48+
49+
Only use the init() function to register services/implementations.
50+
51+
### Settings refactoring
52+
53+
The plan is to move all settings to from package level vars in settings package to the [setting.Cfg](https://github.com/grafana/grafana/blob/df917663e6f358a076ed3daa9b199412e95c11f4/pkg/setting/setting.go#L210) struct. To access the settings, services and components can inject this setting.Cfg struct:
54+
55+
[Cfg struct](https://github.com/grafana/grafana/blob/df917663e6f358a076ed3daa9b199412e95c11f4/pkg/setting/setting.go#L210)
56+
[Injection example](https://github.com/grafana/grafana/blob/df917663e6f358a076ed3daa9b199412e95c11f4/pkg/services/cleanup/cleanup.go#L20)
57+
58+
### Reduce the use of GoConvey
59+
60+
We want to migrate away from using GoConvey. Instead, we want to use stdlib testing, because it's the most common approach in the Go community and we think it will be easier for new contributors. Read more about how we want to write tests in the [style guide](/contribute/backend/style-guide.md).
61+
62+
### Refactor SqlStore
63+
64+
The `sqlstore` handlers all use a global xorm engine variable. Refactor them to use the `SqlStore` instance.
65+
66+
### Avoid global HTTP handler functions
67+
68+
Refactor HTTP handlers so that the handler methods are on the HttpServer instance or a more detailed handler struct. E.g (AuthHandler). This ensures they get access to HttpServer service dependencies (and Cfg object) and can avoid global state.
69+
70+
### Date comparison
71+
72+
Store newly introduced date columns in the database as epochs if they require date comparison. This permits a unified approach for comparing dates against all the supported databases instead of handling dates differently for each database. Also, by comparing epochs, we no longer need error pruning transformations to and from other time zones.
73+
74+
### Avoid use of the simplejson package
75+
76+
Use of the `simplejson` package (`pkg/components/simplejson`) in place of types (Go structs) results in code that is difficult to maintain. Instead, create types for objects and use the Go standard library's [`encoding/json`](https://golang.org/pkg/encoding/json/) package.
77+
78+
### Provisionable\*
79+
80+
All new features that require state should be possible to configure using config files. For example:
81+
82+
- [Data sources](https://github.com/grafana/grafana/tree/main/pkg/services/provisioning/datasources)
83+
- [Alert notifiers](https://github.com/grafana/grafana/tree/main/pkg/services/provisioning/notifiers)
84+
- [Dashboards](https://github.com/grafana/grafana/tree/main/pkg/services/provisioning/dashboards)
85+
86+
Today its only possible to provision data sources and dashboards but this is something we want to support all over Grafana.
87+
88+
### Use context.Context "everywhere"
89+
90+
The package [context](https://golang.org/pkg/context/) should be used and propagated through all the layers of the code. For example the `context.Context` of an incoming API request should be propagated to any other layers being used such as the bus, service and database layers. Utility functions/methods normally doesn't need `context.Context` To follow best practices, any function/method that receives a context.Context argument should receive it as its first argument.
91+
92+
To be able to solve certain problems and/or implement and support certain features making sure that `context.Context` is passed down through all layers of the code is vital. Being able to provide contextual information for the full life-cycle of an API request allows us to use contextual logging, provide contextual information about the authenticated user, create multiple spans for a distributed trace of service calls and database queries etc.
93+
94+
Code should use `context.TODO` when it's unclear which Context to use or it is not yet available (because the surrounding function has not yet been extended to accept a `context.Context` argument).
95+
96+
More details in [Services](/contribute/backend/services.md), [Communication](/contribute/backend/communication.md) and [Database](/contribute/backend/database.md).
97+
98+
[Original design doc](https://docs.google.com/document/d/1ebUhUVXU8FlShezsN-C64T0dOoo-DaC9_r-c8gB2XEU/edit#).
File renamed without changes.
File renamed without changes.
File renamed without changes.

contribute/engineering/backend/instrumentation.md renamed to contribute/backend/instrumentation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ A distributed trace is data that tracks an application request as it flows throu
154154

155155
### Usage
156156

157-
Grafana currently supports two tracing implementations, [OpenTelemetry](https://opentelemetry.io/) and [OpenTracing](https://opentracing.io/). OpenTracing is deprecated, but still supported until we remove it. The two different implementations implements the `Tracer` and `Span` interfaces, defined in the _pkg/infra/tracing_ package, which you can use to create traces and spans. To get a hold of a `Tracer` you would need to get it injected as dependency into your service, see [Services](../../architecture/backend/services.md) for more details.
157+
Grafana currently supports two tracing implementations, [OpenTelemetry](https://opentelemetry.io/) and [OpenTracing](https://opentracing.io/). OpenTracing is deprecated, but still supported until we remove it. The two different implementations implements the `Tracer` and `Span` interfaces, defined in the _pkg/infra/tracing_ package, which you can use to create traces and spans. To get a hold of a `Tracer` you would need to get it injected as dependency into your service, see [Services](services.md) for more details.
158158

159159
Example:
160160

File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)