Skip to content

Commit 87b7168

Browse files
committed
feat(alexandria): give users and distributors the ability to opt out of alexandria
Signed-off-by: Xe Iaso <me@xeiaso.net>
1 parent 3b41af8 commit 87b7168

File tree

10 files changed

+537
-120
lines changed

10 files changed

+537
-120
lines changed

.github/copilot-instructions.md

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
# Copilot Instructions
22

3-
When undertaking a task, take a moment to pause and ask the user what the intent of the task is. Use this to write the best code to fix the problem or implement the feature.
3+
When undertaking a task, take a moment to pause and ask the user what the intent
4+
of the task is. Use this to write the best code to fix the problem or implement
5+
the feature.
46

57
## Code formatting
68

7-
We always write JavaScript with double quotes and two spaces for indentation, so when your responses include JavaScript code, please follow those conventions.
9+
We always write JavaScript with double quotes and two spaces for indentation, so
10+
when your responses include JavaScript code, please follow those conventions.
811

9-
Go code is written in the style of the standard library. When possible, tests are table-driven tests.
12+
Go code is written in the style of the standard library. When possible, tests
13+
are table-driven tests.
1014

1115
All code is formatted with prettier on save, but to run formatting yourself:
1216

@@ -16,7 +20,8 @@ npm run format
1620

1721
## Commit Message Format
1822

19-
Always use conventional commit format for all commit messages. The format should be:
23+
Always use conventional commit format for all commit messages. The format should
24+
be:
2025

2126
```
2227
<type>[optional scope]: <description>
@@ -31,7 +36,8 @@ Always use conventional commit format for all commit messages. The format should
3136
- `feat`: A new feature
3237
- `fix`: A bug fix
3338
- `docs`: Documentation only changes
34-
- `style`: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
39+
- `style`: Changes that do not affect the meaning of the code (white-space,
40+
formatting, missing semi-colons, etc)
3541
- `refactor`: A code change that neither fixes a bug nor adds a feature
3642
- `perf`: A code change that improves performance
3743
- `test`: Adding missing tests or correcting existing tests
@@ -65,15 +71,17 @@ BREAKING CHANGE: User API now requires authentication tokens
6571

6672
### How to commit
6773

68-
When committing, make sure to use double quotes around your commit message, sign off the commit as:
74+
When committing, make sure to use double quotes around your commit message, sign
75+
off the commit as:
6976

7077
```
7178
Mimi Yasomi <mimi.yasomi@techaro.lol>
7279
```
7380

7481
Make sure Mimi is the author too.
7582

76-
Write your commit to a temporary file before committing. Be sure to use the printf command because you're in fish.
83+
Write your commit to a temporary file before committing. Be sure to use the
84+
printf command because you're in fish.
7785

7886
```
7987
printf "<type>[optional scope]: <description>\n\n[optional body]\n\nSigned-off-by: Mimi Yasomi <mimi.yasomi@techaro.lol>"

.prettierrc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,14 @@
33
"tabWidth": 2,
44
"semi": true,
55
"trailingComma": "all",
6-
"printWidth": 80
6+
"printWidth": 80,
7+
"overrides": [
8+
{
9+
"files": ["*.md"],
10+
"options": {
11+
"printWidth": 80,
12+
"proseWrap": "always"
13+
}
14+
}
15+
]
716
}

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
### Bug Fixes
44

5-
- **release:** use the god token ([abca8a6](https://github.com/TecharoHQ/alexandria/commit/abca8a66eafba60d9d7f092f9ee9ca1dde76ca7d))
5+
- **release:** use the god token
6+
([abca8a6](https://github.com/TecharoHQ/alexandria/commit/abca8a66eafba60d9d7f092f9ee9ca1dde76ca7d))
67

78
# 1.0.0 (2025-07-28)

CODE_OF_CONDUCT.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,8 @@ representative at an online or offline event.
5959
## Enforcement
6060

6161
Instances of abusive, harassing, or otherwise unacceptable behavior may be
62-
reported to the community leaders responsible for enforcement at
63-
[INSERT CONTACT METHOD].
64-
All complaints will be reviewed and investigated promptly and fairly.
62+
reported to the community leaders responsible for enforcement at [INSERT CONTACT
63+
METHOD]. All complaints will be reviewed and investigated promptly and fairly.
6564

6665
All community leaders are obligated to respect the privacy and security of the
6766
reporter of any incident.
@@ -118,8 +117,8 @@ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118117
version 2.1, available at
119118
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
120119

121-
Community Impact Guidelines were inspired by
122-
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
120+
Community Impact Guidelines were inspired by [Mozilla's code of conduct
121+
enforcement ladder][Mozilla CoC].
123122

124123
For answers to common questions about this code of conduct, see the FAQ at
125124
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at

README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Alexandria
2+
3+
As in the library.
4+
5+
This is Techaro's log ingestion and aggregation pipeline, with a client for slog
6+
to feed logs into the beast.
7+
8+
## Why does this exist?
9+
10+
In order to make sure that Anubis and related infrastructure bits are working
11+
the best they can, we need to be able to monitor how Anubis is being used in the
12+
real world. Alexandria is the pipeline that ingests logs from customer instances
13+
of Anubis, internal infrastructure, and other sources so that there are fewer
14+
panes of glass to look through when finding information.
15+
16+
Alexandria is the main ingestion component. When Anubis, Thoth, or other
17+
services emit log lines, they buffer them in-memory for up to 32 kilobytes of
18+
logs or one minute (whichever happens first). Then the logs are submitted to
19+
Alexandria, and Alexandria will write them to
20+
[Tigris](https://www.tigrisdata.com).
21+
22+
Once the logs are written to Tigris, Tigris emits
23+
[object notification webhooks](https://www.tigrisdata.com/docs/buckets/object-notifications/)
24+
to serverless functions. These serverless functions will fetch new logs, scrape
25+
them for relevant information, publish those facts internally, and then handle
26+
the next log observation.
27+
28+
## How are logs stored?
29+
30+
All logs are stored according to the following lifecycle rules:
31+
32+
- Logs are ingressed into the Standard storage tier into the `logs` folder.
33+
- One day later, logs are compacted per log ID and moved to the Archive Instant
34+
Retrieval storage tier.
35+
- After 91 days, logs are automatically deleted.
36+
37+
## How do I opt out of this?
38+
39+
For package maintainers, you may opt out of this by building Anubis with the
40+
`limited-support-ability`
41+
[build tag](https://www.digitalocean.com/community/tutorials/customizing-go-binaries-with-build-tags).
42+
Please note that if you do this, Techaro's ability to support your installation
43+
of Anubis or other software will be limited.
44+
45+
For users, you may opt out of this by running Anubis with the
46+
`ANUBIS_LOG_SUBMISSION=i-want-to-make-it-harder-to-get-help` envrionment
47+
variable set.

alexandria/writerwrapper.go

Lines changed: 0 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@ package alexandria
22

33
import (
44
"bytes"
5-
"context"
6-
"fmt"
7-
"io"
8-
"log/slog"
9-
"net/http"
10-
"os"
115
"sync"
126
"time"
137
)
@@ -68,101 +62,3 @@ func (rb *ringBuffer) drain() [][]byte {
6862

6963
return result
7064
}
71-
72-
func Writer(kind string, logID string, next io.Writer) *WriterWrapper {
73-
result := &WriterWrapper{
74-
next: next,
75-
baseURL: defaultAlexandriaURL,
76-
kind: kind,
77-
logID: logID,
78-
rawLog: slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{
79-
AddSource: true,
80-
})),
81-
rb: newRingBuffer(),
82-
done: make(chan struct{}),
83-
}
84-
85-
result.rawLog.Info("starting up logs to alexandria", "kind", kind, "logID", logID, "target", result.baseURL)
86-
87-
// Start the background flush goroutine
88-
go result.flushLoop()
89-
90-
return result
91-
}
92-
93-
type WriterWrapper struct {
94-
rb *ringBuffer
95-
next io.Writer
96-
baseURL string
97-
kind string
98-
logID string
99-
rawLog *slog.Logger
100-
done chan struct{}
101-
}
102-
103-
func (ww *WriterWrapper) SetBaseURL(baseURL string) {
104-
ww.baseURL = baseURL
105-
}
106-
107-
func (ww *WriterWrapper) Write(data []byte) (n int, err error) {
108-
ww.rb.add(data)
109-
return ww.next.Write(data)
110-
}
111-
112-
func (ww *WriterWrapper) flushLoop() {
113-
ticker := time.NewTicker(flushInterval)
114-
defer ticker.Stop()
115-
116-
for {
117-
select {
118-
case <-ticker.C:
119-
ww.flush()
120-
case <-ww.done:
121-
// Final flush before exit
122-
ww.flush()
123-
return
124-
}
125-
}
126-
}
127-
128-
func (ww *WriterWrapper) Close() error {
129-
close(ww.done)
130-
return nil
131-
}
132-
133-
func (ww *WriterWrapper) flush() {
134-
lines := ww.rb.drain()
135-
if len(lines) == 0 {
136-
return
137-
}
138-
139-
ctx, cancel := context.WithTimeout(context.Background(), flushInterval)
140-
defer cancel()
141-
142-
ww.submit(ctx, lines)
143-
}
144-
145-
func (ww *WriterWrapper) submit(ctx context.Context, lines [][]byte) {
146-
buf := bytes.NewBuffer(nil)
147-
148-
for _, line := range lines {
149-
buf.Write(line)
150-
}
151-
152-
req, err := http.NewRequestWithContext(ctx, http.MethodPut, fmt.Sprintf("%s/upload/%s/%s", ww.baseURL, ww.kind, ww.logID), buf)
153-
if err != nil {
154-
ww.rawLog.Error("can't create request to alexandria", "err", err)
155-
return
156-
}
157-
158-
resp, err := http.DefaultClient.Do(req)
159-
if err != nil {
160-
ww.rawLog.Error("can't perform request to alexandria", "err", err)
161-
return
162-
}
163-
164-
if resp.StatusCode != http.StatusOK {
165-
ww.rawLog.Error("wrong alexandria response code", "status", resp.StatusCode, "want", http.StatusOK)
166-
return
167-
}
168-
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//go:build limitedsupportability
2+
3+
package alexandria
4+
5+
import (
6+
"io"
7+
"log/slog"
8+
"os"
9+
)
10+
11+
func Writer(kind string, logID string, next io.Writer) *WriterWrapper {
12+
result := &WriterWrapper{
13+
next: next,
14+
}
15+
16+
lg := slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{
17+
AddSource: true,
18+
}))
19+
20+
lg.Info("Logging to Alexandria has been disabled by build tag. Your ability to recieve support is limited.", "docs", "https://anubis.techaro.lol/docs/admin/alexandria")
21+
22+
return result
23+
}
24+
25+
type WriterWrapper struct {
26+
next io.Writer
27+
}
28+
29+
func (ww *WriterWrapper) SetBaseURL(baseURL string) {}
30+
31+
func (ww *WriterWrapper) Write(data []byte) (n int, err error) {
32+
return ww.next.Write(data)
33+
}

0 commit comments

Comments
 (0)