Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d6df4dd

Browse files
committed
Merge branch '240-artifacts' into 'master'
fix: prepare files to dump and upload statistics artifacts (#240) Closes #240 See merge request postgres-ai/database-lab!291
2 parents 03fb4b2 + 43d975a commit d6df4dd

File tree

2 files changed

+20
-38
lines changed

2 files changed

+20
-38
lines changed

‎pkg/observer/observing_clone.go‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,11 @@ func (c *ObservingClone) resetStat(ctx context.Context) error {
324324
func (c *ObservingClone) storeArtifacts() error {
325325
log.Dbg("Store observation artifacts for SessionID: ", c.session.SessionID)
326326

327+
dstPath := path.Join(c.currentArtifactsSessionPath(), artifactsSubDir)
328+
if err := os.MkdirAll(dstPath, 0666); err != nil {
329+
return errors.Wrapf(err, "cannot create an artifact directory %s", dstPath)
330+
}
331+
327332
ctx := context.Background()
328333

329334
if err := c.dumpStatementsStats(ctx); err != nil {

‎pkg/observer/stats.go‎

Lines changed: 15 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"context"
99
"encoding/json"
1010
"fmt"
11-
"io"
1211
"io/ioutil"
1312
"math/big"
1413
"os"
@@ -114,7 +113,7 @@ func (c *ObservingClone) getMaxQueryTime(ctx context.Context, maxTime *float64)
114113

115114
// countLogErrors counts log errors.
116115
func (c *ObservingClone) countLogErrors(ctx context.Context, logErrors *LogErrors) error {
117-
row := c.superUserDB.QueryRow(ctx, `select sum(count), string_agg(distinct message, ',')
116+
row := c.superUserDB.QueryRow(ctx, `select coalesce(sum(count), 0), coalesce(string_agg(distinct message, ','), '')
118117
from pg_log_errors_stats()
119118
where type in ('ERROR', 'FATAL') and database = current_database()`)
120119

@@ -324,50 +323,28 @@ func (c *ObservingClone) getObjectsSizeStats(ctx context.Context, stat *ObjectsS
324323

325324
// dumpDBStats stores collected statistics.
326325
func (c *ObservingClone) dumpDBStats(ctx context.Context, query, filename string) error {
327-
tempFile, err := ioutil.TempFile("", filename+"_*")
328-
if err != nil {
329-
return errors.Wrap(err, "failed to create temporary file to store statistics")
330-
}
331-
332-
defer func() {
333-
if err := os.Remove(tempFile.Name()); err != nil {
334-
log.Err(err)
335-
}
336-
}()
326+
dstFilePath := path.Join(c.currentArtifactsSessionPath(), artifactsSubDir, filename)
337327

338-
if err := tempFile.Chmod(os.ModePerm); err != nil {
339-
log.Err(err)
328+
if err := initStatFile(dstFilePath); err != nil {
329+
returnerrors.Wrapf(err, "cannot init the stat file %s", dstFilePath)
340330
}
341331

342-
defer func() {
343-
if err := tempFile.Close(); err != nil {
344-
log.Err(err)
345-
}
346-
}()
347-
332+
// Backslash characters (\) can be used in the COPY data to quote data characters
333+
// that might otherwise be taken as row or column delimiters.
334+
// In particular, the following characters must be preceded by a backslash if they appear as part of a column value:
335+
// backslash itself, newline, carriage return, and the current delimiter character.
336+
// https://www.postgresql.org/docs/current/sql-copy.html
337+
//
338+
// It will lead to producing an invalid JSON with double escaped quotes.
339+
// To work around this issue, we can pipe the output of the COPY command to `sed` to revert the double escaping of quotes.
348340
exportQuery := fmt.Sprintf(
349341
`COPY (select coalesce(json_agg(row_to_json(t)), '[]'::json) from (%s) as t) TO PROGRAM $$sed 's/\\\\/\\/g' > %s$$`,
350-
query, tempFile.Name())
342+
query, dstFilePath)
351343
if _, err := c.db.Exec(ctx, exportQuery); err != nil {
352344
return errors.Wrap(err, "failed to export data")
353345
}
354346

355-
dstFilePath := path.Join(c.currentArtifactsSessionPath(), artifactsSubDir, filename)
356-
357-
dstFile, err := os.OpenFile(dstFilePath, os.O_CREATE|os.O_RDWR, os.ModePerm)
358-
if err != nil {
359-
return errors.Wrapf(err, "failed to init the stats file %v", tempFile)
360-
}
361-
362-
defer func() { _ = dstFile.Close() }()
363-
364-
log.Dbg("Dump data into file", dstFile.Name())
365-
366-
if _, err := io.Copy(dstFile, tempFile); err != nil {
367-
return errors.Wrap(err, "failed copy")
368-
}
369-
370-
return err
347+
return nil
371348
}
372349

373350
func (c *ObservingClone) storeFileStats(data []byte, filename string) error {
@@ -390,7 +367,7 @@ func initStatFile(filename string) error {
390367
return err
391368
}
392369

393-
if err := os.Chmod(filename, 0777); err != nil {
370+
if err := os.Chmod(filename, 0666); err != nil {
394371
return err
395372
}
396373

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /