Code Monkey home page Code Monkey logo

xcmetrics's Introduction

XCMetrics is the easiest way to collect Xcode builds metrics and improve your developer productivity.

Build Status License Docker image

Overview

  • ๐Ÿ“ˆ Keep your build times under control and monitor which targets are taking the longest to compile.
  • โš ๏ธ Collect warnings to improve your code health.
  • โŒ Collect errors to help and diagnose builds problems in real-time.
  • ๐Ÿ›  Build custom plugins to collect an infinite amount of metadata to be attached to each build, such as version control information and thermal throttling.

XCMetrics is built on top of XCLogParser, which is a tool that can parse Xcode and xcodebuild logs stored in the xcactivitylog format. This allows XCMetrics to collect accurate metrics for you to review and keep track during the lifetime of a codebase. XCMetrics has collected almost 1 million builds and over 10 billion steps from all Spotify iOS applications since its introduction. It has allowed us to make important and informed decision in regards to our project structure and architecture.

Getting Started

Head over to our Getting Started docs to see how to integrate XCMetrics in your project.

Develop

XCMetrics is built using Swift Package Manager, you just need to open the Package.swift file in Xcode:

xed Package.swift

Support

Create a new issue with as many details as possible. It's important that you follow the issue template and include all required information in order for us to get back to you as soon as possible.

Contributing

We feel that a welcoming community is important and we ask that you follow Spotify's Open Source Code of Conduct in all interactions with the community.

Authors

A full list of contributors can be found on GitHub.

Follow @SpotifyEng on Spotify for updates.

License

Copyright 2020 Spotify, Inc.

Licensed under the Apache License, Version 2.0: https://www.apache.org/licenses/LICENSE-2.0

This product includes software developed by the "Marcin Krzyzanowski" (http://krzyzanowskim.com/).

Security Issues?

Please report sensitive security issues via Spotify's bug-bounty program rather than GitHub.

xcmetrics's People

Contributors

aleksandergrzyb avatar alvarhansen avatar arafo avatar balestrapatrick avatar byohay avatar cognitivedisson avatar dalemyers avatar dlbuckley avatar drunknbass avatar ecamacho avatar evdokimovn avatar hais avatar jkmathew avatar johanbaath avatar louieatfetch avatar luispadron avatar mustiikhalil avatar nabbisen avatar ngranander avatar pavlospt avatar perploug avatar polac24 avatar ronanrodrigo avatar schlagelk avatar simonyang avatar theptrk avatar theykk avatar yanamura avatar yasirmturk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xcmetrics's Issues

Automated XCMetrics setup for projects

Hello! I am impressed by the demo and interested to try out this tool to enhance our developer productivity tooling for Xcode projects. My question: Instead of the manual UI clicking shown in the Getting Started docs, is there a way to automatically (programmatically) set up XCMetrics for a project? If we are to roll this out at scale across all our Xcode-based projects, we would need to have:

  • A single command that can run to set up XCMetrics for that project - no GUI-based configuration
  • A way to share that configuration in the Git repository once set up

Is this possible already, or are there workarounds if not built in? I read through the docs and other issues, and did not see anything related to this.

[Questions] two questions regarding XCMetrics database columns

Hey guys,

after playing around XCMetrics and checking the data saved in database I have two questions just to clarify my information:
1- What is the difference of targets types saved in database (builds or build_targets) for noop, clean, or incremental?
2- What is the difference between duration and compilation duration?

Thank you and have a great day!

`no partition of relation "builds" found for row` error when submitting builds.

Hello, I'm evaluating XCMetrics for our project and run into an error in a quick prototype setup I've created (I've setup the spotify/xcmetrics docker container along with redis, both running in docker compose and also a postgres server that runs outside of docker)

Whenever a build I've configured to send metrics executes, xcmetrics backend contains the following logs:

xcmetrics-dev-1 |[ NOTICE ] 06/10/2023 23:50:18 [ProcessMetricsJob] message dequeued [job_id: 29B6B3C4-49B0-4475-8F9E-1922FF2D474D]
xcmetrics-dev-1 |[ NOTICE ] 06/10/2023 23:50:18 [ProcessMetricsJob] fetching log from file:///tmp/69C932BD-C5E8-43FA-960F-CE58558D6838/267AD278-DF66-4807-BF23-31EBAAACEFF9.xcactivitylog [job_id: 29B6B3C4-49B0-4475-8F9E-1922FF2D474D]
xcmetrics-dev-1 |[ NOTICE ] 06/10/2023 23:50:18 [ProcessMetricsJob] log fetched to file:///tmp/1681F40B-2399-414B-9D29-4B1912040C3D/8A431D3D-FE8D-4899-B45D-B0716775986E.xcactivitylog [job_id: 29B6B3C4-49B0-4475-8F9E-1922FF2D474D]
xcmetrics-dev-1 |[ NOTICE ] 06/10/2023 23:50:26 [ProcessMetricsJob] log parsed file:///tmp/69C932BD-C5E8-43FA-960F-CE58558D6838/267AD278-DF66-4807-BF23-31EBAAACEFF9.xcactivitylog [job_id: 29B6B3C4-49B0-4475-8F9E-1922FF2D474D]
xcmetrics-dev-1 |[ NOTICE ] 06/10/2023 23:50:26 [PostgressMetricsRepository] creating daily partitions
xcmetrics-dev-1 |[ NOTICE ] 06/10/2023 23:50:26 [PostgressMetricsRepository] creating daily partitions
xcmetrics-dev-1 |[ ERROR ] [ProcessMetricsJob] error inserting log from file:///tmp/69C932BD-C5E8-43FA-960F-CE58558D6838/267AD278-DF66-4807-BF23-31EBAAACEFF9.xcactivitylog: server: no partition of relation "builds" found for row (ExecFindPartition) [job_id: 29B6B3C4-49B0-4475-8F9E-1922FF2D474D]
xcmetrics-dev-1 |[ ERROR ] Job failed, retrying... server: no partition of relation "builds" found for row (ExecFindPartition) [job_id: 29B6B3C4-49B0-4475-8F9E-1922FF2D474D, job_name: ProcessMetricsJob, queue: default]
xcmetrics-dev-1 |[ NOTICE ] 06/10/2023 23:50:26 [ProcessMetricsJob] message dequeued [job_id: 29B6B3C4-49B0-4475-8F9E-1922FF2D474D]
xcmetrics-dev-1 |[ NOTICE ] 06/10/2023 23:50:26 [ProcessMetricsJob] fetching log from file:///tmp/69C932BD-C5E8-43FA-960F-CE58558D6838/267AD278-DF66-4807-BF23-31EBAAACEFF9.xcactivitylog [job_id: 29B6B3C4-49B0-4475-8F9E-1922FF2D474D]
xcmetrics-dev-1 |[ NOTICE ] 06/10/2023 23:50:26 [ProcessMetricsJob] log fetched to file:///tmp/1530E5C8-B77F-4A74-863D-A858905CFE1C/07DC4EB1-BC0D-4293-AB99-70C763F77DA0.xcactivitylog [job_id: 29B6B3C4-49B0-4475-8F9E-1922FF2D474D]
xcmetrics-dev-1 |[ NOTICE ] 06/10/2023 23:50:34 [ProcessMetricsJob] log parsed file:///tmp/69C932BD-C5E8-43FA-960F-CE58558D6838/267AD278-DF66-4807-BF23-31EBAAACEFF9.xcactivitylog [job_id: 29B6B3C4-49B0-4475-8F9E-1922FF2D474D]
xcmetrics-dev-1 |[ NOTICE ] 06/10/2023 23:50:34 [PostgressMetricsRepository] creating daily partitions
xcmetrics-dev-1 |[ NOTICE ] 06/10/2023 23:50:34 [PostgressMetricsRepository] creating daily partitions
xcmetrics-dev-1 |[ ERROR ] [ProcessMetricsJob] error inserting log from file:///tmp/69C932BD-C5E8-43FA-960F-CE58558D6838/267AD278-DF66-4807-BF23-31EBAAACEFF9.xcactivitylog: server: no partition of relation "builds" found for row (ExecFindPartition) [job_id: 29B6B3C4-49B0-4475-8F9E-1922FF2D474D]
...

and then my postgres server contains the following:

2023-10-06 16:50:42.305 PDT [70258] STATEMENT:  INSERT INTO "builds" ("tag", "category", "compiled_count", "machine_name", "duration", "start_timestamp_microseconds", "project_name", "error_count", "user_id", "user_id_256", "start_timestamp", "warning_count", "compilation_end_timestamp_microseconds", "was_suspended", "compilation_duration", "day", "id", "end_timestamp", "build_status", "schema", "end_timestamp_microseconds", "is_ci", "compilation_end_timestamp") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23) RETURNING "id"
2023-10-06 16:50:50.163 PDT [70258] ERROR:  no partition of relation "builds" found for row
2023-10-06 16:50:50.163 PDT [70258] DETAIL:  Partition key of the failing row contains (day) = (2023-10-05).

from a cursory look, database tables appear to have been initialized, but the only one that is populated upon a build is job_log_entries, each build creating a row that looks roughly like this:

[
  {
    "id": "29B6B3C4-49B0-4475-8F9E-1922FF2D474D",
    "log_file": "267AD278-DF66-4807-BF23-31EBAAACEFF9.xcactivitylog",
    "log_url": "file:///tmp/69C932BD-C5E8-43FA-960F-CE58558D6838/267AD278-DF66-4807-BF23-31EBAAACEFF9.xcactivitylog",
    "status": "failed",
    "error": "server: no partition of relation \"builds\" found for row (ExecFindPartition)",
    "queued_at": "2023-10-06 23:50:18.634539 +00:00",
    "dequeued_at": "2023-10-06 23:50:18.917057 +00:00",
    "finished_at": "2023-10-06 23:50:50.225589 +00:00",
    "created_at": "2023-10-06 23:50:18.635936 +00:00",
    "updated_at": "2023-10-06 23:50:50.225608 +00:00"
  }
]

I'd appreciate any guidance on how to troubleshoot and/or fix this issue so I could continue my evaluation.

Question: Will and when uploaded xcactivitylog be deleted?

Hi there
As far as i know xcmetrics will copied xcactivitylog from derived data to ~/Library/Caches/XCMetrics, So I think, the longer this folder will contain a lot of .xcactivitylogs and will require a lot of storage space on the hard disk,
Can xcmetrics delete xcactivitylog automatically? perhaps Instead of renaming the file with UPLOADED.xcactivitylog can we just delete it?

Stuck booting XCMetricsBackend when deploying using scheduled job

I encountered issue when deploying using docker-compoese, following the documentation provided.

command: ["./XCMetricsBackend",
                  "queues",
                  "--scheduled",
                  "--env",
                  "production"]

Turns out that the command does not take exec path. In my case I should change to

command: [ "queues",
                  "--scheduled",
                  "--env",
                  "production"]

After change it, in my xcmetrics service, it will stuck when booting and only produce this log

[ NOTICE ] Connecting to xcmetrics in postgresql as xcmetrics password length 15

[ INFO ] Using redis host redis and port 6379

[ INFO ] Starting scheduled jobs worker

I cannot connect to localhost:8080 using browser, even after 10 minutes waiting for the service to boot up.

Is there any change this is because the service boot command is overridden and the service in port 8080 is not started yet?
When I see docker documentation, command property is used to override default command which in XCMetrics Dockerfile is

# Start the Vapor service when the image is run, default to listening on 8080 in production environment
ENTRYPOINT ["./XCMetricsBackend"]
CMD ["serve", "--auto-migrate", "--env", "production", "--hostname", "0.0.0.0", "--port", "8080"]

failed to create connection for pool [error: connection reset (error set): No route to host (errno: 113)

We are seeing below error.


postgresql_1  | PostgreSQL Database directory appears to contain a database; Skipping initialization
postgresql_1  | 
postgresql_1  | 2021-05-20 17:51:24.211 UTC [1] LOG:  starting PostgreSQL 13.3 (Debian 13.3-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
redis_1       | 1:C 20 May 2021 17:51:24.191 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1       | 1:C 20 May 2021 17:51:24.191 # Redis version=6.2.3, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1       | 1:C 20 May 2021 17:51:24.191 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
xcmetrics_1   | [ NOTICE ] Connecting to xcmetrics-dev in ****** as xcmetrics-dev password length 13
xcmetrics_1   | [ INFO ] Using redis host ******* and port 6379
redis_1       | 1:M 20 May 2021 17:51:24.192 * monotonic clock: POSIX clock_gettime
postgresql_1  | 2021-05-20 17:51:24.214 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
redis_1       | 1:M 20 May 2021 17:51:24.195 # Warning: Could not create server TCP listening socket ::*:6379: unable to bind socket, errno: 97
redis_1       | 1:M 20 May 2021 17:51:24.195 * Running mode=standalone, port=6379.
redis_1       | 1:M 20 May 2021 17:51:24.196 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis_1       | 1:M 20 May 2021 17:51:24.196 # Server initialized
redis_1       | 1:M 20 May 2021 17:51:24.196 * Ready to accept connections
postgresql_1  | 2021-05-20 17:51:24.216 UTC [1] LOG:  could not create IPv6 socket for address "::": Address family not supported by protocol
postgresql_1  | 2021-05-20 17:51:24.222 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgresql_1  | 2021-05-20 17:51:24.233 UTC [25] LOG:  database system was shut down at 2021-05-20 17:42:18 UTC
postgresql_1  | 2021-05-20 17:51:24.240 UTC [1] LOG:  database system is ready to accept connections
postgresql_1  | 2021-05-20 17:51:34.222 UTC [38] FATAL:  role "xcmetricsdb" does not exist
postgresql_1  | 2021-05-20 17:51:44.371 UTC [45] FATAL:  role "xcmetricsdb" does not exist
postgresql_1  | 2021-05-20 17:51:54.518 UTC [53] FATAL:  role "xcmetricsdb" does not exist
xcmetrics_1   | [ ERROR ] failed to create connection for pool [error: connection reset (error set): No route to host (errno: 113), rdstk_conpool_id: 49365023-7B19-4F38-B99E-BF9F35C3DC3E]
xcmetrics_1   | [ ERROR ] failed to create connection for pool [error: connection reset (error set): No route to host (errno: 113), rdstk_conpool_id: 49365023-7B19-4F38-B99E-BF9F35C3DC3E]
xcmetrics_1   | [ ERROR ] Job run failed: RedisConnectionPoolError(baseError: RediStack.RedisConnectionPoolError.BaseError.timedOutWaitingForConnection)

Failure to compile with Xcode 14

Looks like with the Xcode 14 and Swift 5.6 stack, XCMetrics fails to compile.

The error I'm receiving is here:

[1308/1314] Compiling Vapor Application.swift
/private/var/folders/5v/z721gx9s29d54dfpy2znzmd80000gn/T/mint/github.com_spotify_XCMetrics/.build/checkouts/vapor/Sources/Vapor/HTTP/Headers/HTTPHeaders+Directive.swift:230:14: error: ambiguous use of 'split(separator:maxSplits:omittingEmptySubsequences:)'
        self.lazy.split(separator: "\\").reduce(into: "") { (result, part) in
             ^
Swift.Sequence:2:40: note: found this candidate
    @inlinable public __consuming func split(separator: Self.Element, maxSplits: Int = Int.max, omittingEmptySubsequences: Bool = true) -> [ArraySlice<Self.Element>]
                                       ^
Swift.Collection:2:40: note: found this candidate
    @inlinable public __consuming func split(separator: Self.Element, maxSplits: Int = Int.max, omittingEmptySubsequences: Bool = true) -> [Self.SubSequence]

It looks like this is an error in the Vapor library which has been fixed a few versions ago. I think if we bump the version of that dependency it would probably fix the issue. Thanks!

NIOPostgres error: protocol error: Bind count must be <= 32767

When attempting to upload an XCActivityLog that is rather large (29.1 MB) with many targets, and many steps, XCMetrics logs an error: [ ERROR ] Uncaught error: NIOPostgres error: protocol error: Bind count must be <= 32767.

A Google search for that error pointed me to: vapor/fluent-kit#277. It seems to be related to the number of parameters that are being bound to a given query.

Here is what the breakpoint looks like after the log is parsed in the insert method of the PostgreSQLMetricsRepository struct.

Screen Shot 2021-02-17 at 11 43 05 PM

Here is the raw log output:

[ INFO ] PUT /v1/metrics [request-id: 8C8BB0F4-A820-4661-9CD9-30CEE2C6A0B0]
[ INFO ] Dispatched queue job [job_id: 9170D075-D21B-4204-9E87-7D693A934C7B, job_name: ProcessMetricsJob, queue: default, request-id: 8C8BB0F4-A820-4661-9CD9-30CEE2C6A0B0]
[ INFO ] PUT /v1/metrics [request-id: F0778FB1-7894-46C8-A053-6F236902A751]
[ INFO ] Dispatched queue job [job_id: 5995640B-3785-48A5-B4BD-08593C61822A, job_name: ProcessMetricsJob, queue: default, request-id: F0778FB1-7894-46C8-A053-6F236902A751]
[ INFO ] Dequeing job [job_id: 9170D075-D21B-4204-9E87-7D693A934C7B, job_name: ProcessMetricsJob, queue: default]
[ NOTICE ] 17/02/2021 23:24:35 [ProcessMetricsJob] message dequeued [job_id: 9170D075-D21B-4204-9E87-7D693A934C7B]
[ NOTICE ] 17/02/2021 23:24:35 [ProcessMetricsJob] fetching log from file:///var/folders/rm/0tz8w5hx4kb597326bxp7ksh0000gn/T/5A1D12F4-5F8F-4ECB-8225-E38746464152/2C2594C3-4B6C-4F07-9145-461019452E4C.xcactivitylog [job_id: 9170D075-D21B-4204-9E87-7D693A934C7B]
[ NOTICE ] 17/02/2021 23:24:35 [ProcessMetricsJob] log fetched to file:///var/folders/rm/0tz8w5hx4kb597326bxp7ksh0000gn/T/5A1D12F4-5F8F-4ECB-8225-E38746464152/2C2594C3-4B6C-4F07-9145-461019452E4C.xcactivitylog [job_id: 9170D075-D21B-4204-9E87-7D693A934C7B]
[ INFO ] Dequeing job [job_id: 5995640B-3785-48A5-B4BD-08593C61822A, job_name: ProcessMetricsJob, queue: default]
[ NOTICE ] 17/02/2021 23:24:35 [ProcessMetricsJob] message dequeued [job_id: 5995640B-3785-48A5-B4BD-08593C61822A]
[ NOTICE ] 17/02/2021 23:29:11 [ProcessMetricsJob] log parsed file:///var/folders/rm/0tz8w5hx4kb597326bxp7ksh0000gn/T/5A1D12F4-5F8F-4ECB-8225-E38746464152/2C2594C3-4B6C-4F07-9145-461019452E4C.xcactivitylog [job_id: 9170D075-D21B-4204-9E87-7D693A934C7B]
[ NOTICE ] 17/02/2021 23:29:11 [ProcessMetricsJob] fetching log from file:///var/folders/rm/0tz8w5hx4kb597326bxp7ksh0000gn/T/276EEDC9-A774-408C-B14E-9C04124D377C/5100D986-E078-4BD8-A894-9163DD594967.xcactivitylog [job_id: 5995640B-3785-48A5-B4BD-08593C61822A]
[ NOTICE ] 17/02/2021 23:29:11 [ProcessMetricsJob] log fetched to file:///var/folders/rm/0tz8w5hx4kb597326bxp7ksh0000gn/T/276EEDC9-A774-408C-B14E-9C04124D377C/5100D986-E078-4BD8-A894-9163DD594967.xcactivitylog [job_id: 5995640B-3785-48A5-B4BD-08593C61822A]
[ NOTICE ] 17/02/2021 23:29:11 [PostgressMetricsRepository] creating daily partitions
[ NOTICE ] 17/02/2021 23:29:11 [ProcessMetricsJob] log parsed file:///var/folders/rm/0tz8w5hx4kb597326bxp7ksh0000gn/T/276EEDC9-A774-408C-B14E-9C04124D377C/5100D986-E078-4BD8-A894-9163DD594967.xcactivitylog [job_id: 5995640B-3785-48A5-B4BD-08593C61822A]
[ NOTICE ] 17/02/2021 23:29:11 [PostgressMetricsRepository] creating daily partitions
[ NOTICE ] 17/02/2021 23:29:11 [PostgressMetricsRepository] creating daily partitions
[ NOTICE ] 17/02/2021 23:29:11 [PostgressMetricsRepository] creating daily partitions
[ ERROR ] Uncaught error: NIOPostgres error: protocol error: Bind count must be <= 32767.
[ NOTICE ] 17/02/2021 23:29:16 [PostgressMetricsRepository] metrics inserted
[ INFO ] [ProcessMetricsJob] metrics inserted for file:///var/folders/rm/0tz8w5hx4kb597326bxp7ksh0000gn/T/276EEDC9-A774-408C-B14E-9C04124D377C/5100D986-E078-4BD8-A894-9163DD594967.xcactivitylog [job_id: 5995640B-3785-48A5-B4BD-08593C61822A]
[ INFO ] [ProcessMetricsJob] finished processing file:///var/folders/rm/0tz8w5hx4kb597326bxp7ksh0000gn/T/276EEDC9-A774-408C-B14E-9C04124D377C/5100D986-E078-4BD8-A894-9163DD594967.xcactivitylog [job_id: 5995640B-3785-48A5-B4BD-08593C61822A]```

Log not send when executed from terminal via xcodebuild.

I have been gathering logs compiling directly from Xcode without problem. I tried to run the xcodebuild command to automate some experiments, and i noticed the log are not being sent.

I have redirected the output of the post action to a file, but nothing is printed there. I run the same project unmodified from Xcode and the logs are sent with no problem.

Any tips or pointers will be appreciated!

Track xcodebuild xcactivitylog when running unit testing

Hallo guys, i have tried to use XCMetrics to track xcodebuild data, and the result is awesome
and may i know is it possible to integrate xcmetrics into Unit Test Scheme Post Actions?
So i can know that build is used to run unit test

Update XCLogParser to v0.2.37

It seems that with the introduction of Xcode 15, there's a new "class instance" type: IDEActivityLogActionMessage.

This was fixed in v0.2.37 and the dependency should be updated here otherwise you'll get this error with parsing build logs.

MobileNativeFoundation/XCLogParser#187

Creating an issue here so I can reference a PR.

Some fields are empty in the `build_hosts` table

I am seeing some fields like host_os, host_architecture, host_os_version, cpu_model are empty in the build_hosts table. Also, integer fields like cpu_count, memory_total_mb, swap_total_mb etc are 0. Is this because of some configuration issue or something I am doing wrong?

Another issue I am seeing is CPU model is Apple M1 Pro but the CPU architecture is x86_64, is this because the developer enabled Rosseta for their Xcode?
Screenshot 2023-09-19 at 10 46 13

Web interface

Hi!
I'm trying XCMetrics to see how we can leverage it within our organization.
One thing that it is not clear to me is whether the web interface that is shown in the presentation video is included in the project.

I've read the documentation and deployed locally the server, but it looks like there is only the part of the backend that gather metrics. Is that correct?

Thanks a lot

Pin GoogleCloudKit version or update platform to 13.0

Recently Vapor has updated GoogleCloudKit platform to .macOS(.v13) Which causes build errors like the following for packages using XCMetrics as a dependency.

[0/1] Planning builderror: the library 'XCMetricsBackendLib' requires macos 10.15, 
but depends on the product 'GoogleCloudKit' which requires macos 13.0; 
consider changing the library 'XCMetricsBackendLib' to require macos 13.0 or later, 
or the product 'GoogleCloudKit' to require macos 10.15 or earlier.

To fix this,
Either pin GoogleCloudKit to 1.0.0-rc.9
or update 'XCMetricsBackendLib' to require macos 13.0 or later

Error connecting to postgres when running docker compose local

Steps to reproduce

Clone the repo and run
โฏ docker-compose -f docker-compose-local.yml up
I get the error:
xcmetrics_1 | Fatal error: Error raised at top level: NIOPostgres error: connection closed: file Swift/ErrorType.swift, line 200

Full output:

Creating network "xcmetrics_default" with the default driver
Creating xcmetrics_redis_1      ... done
Creating xcmetrics_postgresql_1 ... done
Creating xcmetrics_xcmetrics_1  ... done
Attaching to xcmetrics_redis_1, xcmetrics_postgresql_1, xcmetrics_xcmetrics_1
postgresql_1  |
postgresql_1  | PostgreSQL Database directory appears to contain a database; Skipping initialization
postgresql_1  |
redis_1       | 1:C 04 Oct 2021 12:19:40.636 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1       | 1:C 04 Oct 2021 12:19:40.636 # Redis version=6.2.5, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1       | 1:C 04 Oct 2021 12:19:40.636 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis_1       | 1:M 04 Oct 2021 12:19:40.637 * monotonic clock: POSIX clock_gettime
postgresql_1  | 2021-10-04 12:19:40.704 UTC [1] LOG:  starting PostgreSQL 14.0 (Debian 14.0-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
redis_1       | 1:M 04 Oct 2021 12:19:40.639 * Running mode=standalone, port=6379.
redis_1       | 1:M 04 Oct 2021 12:19:40.639 # Server initialized
postgresql_1  | 2021-10-04 12:19:40.705 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
postgresql_1  | 2021-10-04 12:19:40.705 UTC [1] LOG:  listening on IPv6 address "::", port 5432
redis_1       | 1:M 04 Oct 2021 12:19:40.640 * Ready to accept connections
postgresql_1  | 2021-10-04 12:19:40.708 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgresql_1  | 2021-10-04 12:19:40.716 UTC [27] LOG:  database system was interrupted; last known up at 2021-10-01 11:48:39 UTC
postgresql_1  | 2021-10-04 12:19:40.926 UTC [27] LOG:  database system was not properly shut down; automatic recovery in progress
postgresql_1  | 2021-10-04 12:19:40.929 UTC [27] LOG:  redo starts at 0/16FB6C8
postgresql_1  | 2021-10-04 12:19:40.929 UTC [27] LOG:  invalid record length at 0/16FB700: wanted 24, got 0
postgresql_1  | 2021-10-04 12:19:40.929 UTC [27] LOG:  redo done at 0/16FB6C8 system usage: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
postgresql_1  | 2021-10-04 12:19:40.943 UTC [1] LOG:  database system is ready to accept connections
xcmetrics_1   | [ NOTICE ] Connecting to xcmetrics-dev in postgresql as xcmetrics-dev password length 13
xcmetrics_1   | [ INFO ] Using redis host redis and port 6379
xcmetrics_1   | [ ERROR ] Uncaught error: NIOPostgres error: protocol error: Unkonwn authentication request type: 10
xcmetrics_1   | [ ERROR ] NIOPostgres error: connection closed
xcmetrics_1   | [ ERROR ] error while closing connection [error: alreadyClosed, rdstk_conn_id: F4F8AE96-8132-4009-8886-0A89A913ACEA, rdstk_conpool_id: B248BA6F-A666-404D-98FF-98AF53133DDF]
xcmetrics_1   | [ ERROR ] error while closing connection [error: alreadyClosed, rdstk_conn_id: 7E83E938-0D19-4DAE-A65B-F0FFEB602468, rdstk_conpool_id: B248BA6F-A666-404D-98FF-98AF53133DDF]
xcmetrics_1   | Fatal error: Error raised at top level: NIOPostgres error: connection closed: file Swift/ErrorType.swift, line 200
xcmetrics_1   | Current stack trace:
xcmetrics_1   | 0    libswiftCore.so                    0x00007f48c27cc990 swift_reportError + 50
xcmetrics_1   | 1    libswiftCore.so                    0x00007f48c2840260 _swift_stdlib_reportFatalErrorInFile + 115
xcmetrics_1   | 2    libswiftCore.so                    0x00007f48c2525925 <unavailable> + 1399077
xcmetrics_1   | 3    libswiftCore.so                    0x00007f48c2525567 <unavailable> + 1398119
xcmetrics_1   | 4    libswiftCore.so                    0x00007f48c2525b02 <unavailable> + 1399554
xcmetrics_1   | 5    libswiftCore.so                    0x00007f48c2523fa0 _assertionFailure(_:_:file:line:flags:) + 517
xcmetrics_1   | 6    libswiftCore.so                    0x00007f48c258d6b6 <unavailable> + 1824438
xcmetrics_1   | 7    XCMetricsBackend                   0x000055a23458d3b1 <unavailable> + 15336369
xcmetrics_1   | 8    libc.so.6                          0x00007f48bfae9b10 __libc_start_main + 231
xcmetrics_1   | 9    XCMetricsBackend                   0x000055a2338cb6ea <unavailable> + 1959658
xcmetrics_1   | 0x7f48c19e997f
xcmetrics_1   | 0x7f48c25241b2
xcmetrics_1   | 0x7f48c258d6b5
xcmetrics_1   | 0x55a23458d3b0, main at /build/<compiler-generated>:0
xcmetrics_1   | 0x7f48bfae9bf6
xcmetrics_1   | 0x55a2338cb6e9
xcmetrics_1   | 0xffffffffffffffff
xcmetrics_xcmetrics_1 exited with code 132

Seems a problem with the latest Postgres docker image

Workaround

In order to be able to run XCMetrics locally with docker compose locally, I edited docker-compose-local.yml by replacing:
image: postgres
with
image: postgres:13.4

How to delete old data

Hello, Im trying to use docker-compose-local.yml and my postgres database is growing
Is there any build in solution to delete old data? Or I can just drop old partitions?

Tag and hardware information are missing from the build information

Adding a tag using the environment variable SPT_XCMETRICS_TAG doesn't have any effect. When querying the database the tag comes back empty. I know I set it correctly in the client because I saw the line Started appending a tag "SomeTag" being printed to the Console.
The same is true for some of the fields in build/host/:id endpoint

I strongly suspect it has something to do with the AddMetadataEffectHandler.

Skip post-action for clean tasks

We're currently seeing quite a lot of noise generated by clean builds (which on CI is before every real build). Is there a way to prevent the post-action script from being called when we're simply cleaning?

Could this be a case of ignoring the 'noop' category?

Add a new endpoint to filter build metadata

Hi!

I would love the ability to filter build metadata by key / value

For example:
Build 1 metadata
[ "git_commit_sha": "build_1_sha.", "git_branch": "a_git_branch" "key_x": "another_value" ... ]

Build 2 metadata
[ "git_commit_sha": "build_2_sha", "git_branch": "a_git_branch" "key_x": "another_value" ... ]

By being able to filter metadata by git_branch for example, I'd be able to get additional metadata fields from other builds which could help to analyze possible improvements or regressions.

Happy to propose an implementation if this is a welcomed addition.

Thanks!

Upload client stuck when there's no failed upload

I'm triggering the xcmetric binary through scripts and didn't use the launcher. I notice that occasionally xcmetric runs forever when I trigger it without any new xcactivitylog.

I did a very brief skim on the source code, please kindly correct me if I'm wrong:

In MetricUploaderLogic.swift, it seems both cleanedUpLogs and savedUploadRequests need to be received before we can send mobiusLoopCompleted? For my cases, I never received savedUploadRequests.

Then I trace it back to UploadMetricsEffectHandler.swift, line 42, there's an empty check

if !failedURLs.isEmpty {
    effects.append(.logsUploadFailed(logs: failedURLs))
}

So it seems when nothing fails, the logsUploadFailed will be skipped, and consequently persistNonUploadedLogs will not be triggered, so in the end no savedUploadRequests events will be emitted.

Currently I removed the empty check and it seems to work for my cases now. Have I understood the problem correctly? And will there be any other unwanted side effects if I remove the empty check?

Crash when parsing activity log file

We use the latest docker image and Xcode 12.1.

The crash log:

[ NOTICE ] 22/03/2021 17:06:05 [ProcessMetricsJob] fetching log from file:///tmp/7277A4A2-7D1D-4FE5-BDA3-BCFCD68157DC/D6F72682-AEE4-466F-8DCE-FCA4A027B08F.xcactivitylog [job_id: 4DE44B28-C790-462D-A6C9-1AA8E556C4C7]
[ NOTICE ] 22/03/2021 17:06:05 [ProcessMetricsJob] log fetched to file:///tmp/7277A4A2-7D1D-4FE5-BDA3-BCFCD68157DC/D6F72682-AEE4-466F-8DCE-FCA4A027B08F.xcactivitylog [job_id: 4DE44B28-C790-462D-A6C9-1AA8E556C4C7]
0x7fd68045d97f
0x5598e503ee3f, Swift runtime failure: Unexpectedly found nil while unwrapping an Optional value at .build/checkouts/xclogparser/Sources/XCLogParser/parser/SwiftCompilerTimeOptionParser.swift:0
0x5598e503ee3f, function signature specialization <Arg[1] = Dead> of generic specialization <XCLogParser.SwiftCompilerTypeCheckOptionParser> of (extension in XCLogParser):XCLogParser.SwiftCompilerTimeOptionParser.parseNameAndLocation(from: Swift.String) -> Swift.Optional<(Swift.String, Swift.Int, Swift.Int)> at .build/checkouts/xclogparser/Sources/XCLogParser/parser/SwiftCompilerTimeOptionParser.swift:59
0x5598e503ee3f, generic specialization <XCLogParser.SwiftCompilerTypeCheckOptionParser> of (extension in XCLogParser):XCLogParser.SwiftCompilerTimeOptionParser.parseNameAndLocation(from: Swift.String) -> Swift.Optional<(Swift.String, Swift.Int, Swift.Int)> at /build/<compiler-generated>:0
0x5598e503ee3f, closure #1 (Swift.String) -> Swift.Optional<XCLogParser.SwiftTypeCheck> in XCLogParser.SwiftCompilerTypeCheckOptionParser.(parse in _EDF18D047378C5B6247F84B294158F58)(command: Swift.String, occurrences: Swift.Int) -> Swift.Optional<Swift.Array<XCLogParser.SwiftTypeCheck>> at /build/.build/checkouts/xclogparser/Sources/XCLogParser/parser/SwiftCompilerTypeCheckOptionParser.swift:61
0x5598e503ee3f, reabstraction thunk helper from @callee_guaranteed (@guaranteed Swift.String) -> (@owned Swift.Optional<XCLogParser.SwiftTypeCheck>, @error @owned Swift.Error) to @escaping @callee_guaranteed (@in_guaranteed Swift.String) -> (@out Swift.Optional<XCLogParser.SwiftTypeCheck>, @error @owned Swift.Error) at /build/<compiler-generated>:0
0x5598e503ee3f, generic specialization <Swift.Array<Swift.String>, XCLogParser.SwiftTypeCheck> of (extension in Swift):Swift.Sequence.compactMap<A>((A.Element) throws -> Swift.Optional<A1>) throws -> Swift.Array<A1> at /build/<compiler-generated>:0
0x5598e503ee3f, XCLogParser.SwiftCompilerTypeCheckOptionParser.(parse in _EDF18D047378C5B6247F84B294158F58)(command: Swift.String, occurrences: Swift.Int) -> Swift.Optional<Swift.Array<XCLogParser.SwiftTypeCheck>> at /build/.build/checkouts/xclogparser/Sources/XCLogParser/parser/SwiftCompilerTypeCheckOptionParser.swift:48
0x5598e503ee3f, closure #1 ((key: Swift.String, value: Swift.Int)) -> Swift.Optional<Swift.Array<XCLogParser.SwiftTypeCheck>> in XCLogParser.SwiftCompilerTypeCheckOptionParser.parse(from: Swift.Dictionary<Swift.String, Swift.Int>) -> Swift.Dictionary<Swift.String, Swift.Array<XCLogParser.SwiftTypeCheck>> at /build/.build/checkouts/xclogparser/Sources/XCLogParser/parser/SwiftCompilerTypeCheckOptionParser.swift:33
0x5598e503ee3f, reabstraction thunk helper from @callee_guaranteed (@guaranteed Swift.String, @unowned Swift.Int) -> (@owned Swift.Optional<Swift.Array<XCLogParser.SwiftTypeCheck>>, @error @owned Swift.Error) to @escaping @callee_guaranteed (@in_guaranteed (key: Swift.String, value: Swift.Int)) -> (@out Swift.Optional<Swift.Array<XCLogParser.SwiftTypeCheck>>, @error @owned Swift.Error) at /build/<compiler-generated>:0
0x5598e503ee3f, generic specialization <Swift.Dictionary<Swift.String, Swift.Int>, Swift.Array<XCLogParser.SwiftTypeCheck>> of (extension in Swift):Swift.Sequence.compactMap<A>((A.Element) throws -> Swift.Optional<A1>) throws -> Swift.Array<A1> at /build/<compiler-generated>:0
0x5598e503ee3f, XCLogParser.SwiftCompilerTypeCheckOptionParser.parse(from: Swift.Dictionary<Swift.String, Swift.Int>) -> Swift.Dictionary<Swift.String, Swift.Array<XCLogParser.SwiftTypeCheck>> at /build/.build/checkouts/xclogparser/Sources/XCLogParser/parser/SwiftCompilerTypeCheckOptionParser.swift:33
0x5598e503d9a4, XCLogParser.SwiftCompilerParser.parse() -> () at /build/.build/checkouts/xclogparser/Sources/XCLogParser/parser/SwiftCompilerParser.swift:73
0x5598e502d872, XCLogParser.ParserBuildSteps.(decorateWithSwiftcTimes in _3469993AC311903DEC578A49106939F6)(XCLogParser.BuildStep) -> XCLogParser.BuildStep at /build/.build/checkouts/xclogparser/Sources/XCLogParser/parser/ParserBuildSteps.swift:298
0x5598e5028456, XCLogParser.ParserBuildSteps.parse(activityLog: XCLogParser.IDEActivityLog) throws -> XCLogParser.BuildStep at /build/.build/checkouts/xclogparser/Sources/XCLogParser/parser/ParserBuildSteps.swift:95
0x5598e50b7258, function signature specialization <Arg[7] = Dead> of static XCMetricsBackendLib.LogParser.parseFromURL(_: Foundation.URL, machineName: Swift.String, projectName: Swift.String, userId: Swift.String, userIdSHA256: Swift.String, isCI: Swift.Bool, sleepTime: Swift.Optional<Swift.Int>) throws -> XCMetricsBackendLib.BuildMetrics at /build/Sources/XCMetricsBackendLib/UploadMetrics/LogProcessing/LogParser.swift:54
0x5598e50b7dd0, static XCMetricsBackendLib.LogParser.parseFromURL(_: Foundation.URL, machineName: Swift.String, projectName: Swift.String, userId: Swift.String, userIdSHA256: Swift.String, isCI: Swift.Bool, sleepTime: Swift.Optional<Swift.Int>) throws -> XCMetricsBackendLib.BuildMetrics at /build/<compiler-generated>:0
0x5598e50b7dd0, function signature specialization <Arg[3] = Dead> of static XCMetricsBackendLib.MetricsProcessor.process(metricsRequest: XCMetricsBackendLib.UploadMetricsRequest, logURL: Foundation.URL, redactUserData: Swift.Bool) throws -> XCMetricsBackendLib.BuildMetrics at /build/Sources/XCMetricsBackendLib/UploadMetrics/LogProcessing/MetricsProcessor.swift:13
0x5598e50a7812, static XCMetricsBackendLib.MetricsProcessor.process(metricsRequest: XCMetricsBackendLib.UploadMetricsRequest, logURL: Foundation.URL, redactUserData: Swift.Bool) throws -> XCMetricsBackendLib.BuildMetrics at /build/<compiler-generated>:0
0x5598e50a7812, closure #1 () -> () in XCMetricsBackendLib.ProcessMetricsJob.dequeue(Queues.QueueContext, XCMetricsBackendLib.UploadMetricsRequest) -> NIO.EventLoopFuture<()> at /build/Sources/XCMetricsBackendLib/UploadMetrics/Jobs/ProcessMetricsJob.swift:68
0x5598e444d68d, reabstraction thunk helper from @escaping @callee_guaranteed () -> () to @escaping @callee_unowned @convention(block) () -> () at /build/<compiler-generated>:0
0x7fd67fa68406
0x7fd67fa73c28
0x7fd67fa748cd
0x7fd67fa7c521
0x7fd6804526da
0x7fd67e65d71e
0xffffffffffffffff

I create issue on XCLogParser

[doc] Is there any documentation about the database schema, table?

I try to use Grafana to create metrics that will view data sources in Postgres directly. so I need to know the data, the schemas, and their tables, data relationship in each table. Are there any documents about them?
I can guess most of the tables, columns, but it will be easy if we have documentation about them.

Build log greater than 1MB crash XCMetrics Backend when writing to Postgres

I have been trying to setup XCMetrics for a large application I work on as part of my day job.

There is an issue when processing the build logs as it seems to time out the connection to Postgres, which in turn crashes the xcmetrics container.

Then the next line in the logs is the xcmetrics backend rebooting (i've got restart always on in my docker compose file).

I tried experimenting using a much smaller app to see if it was related to log size - and it appears that the log size is the cause of the issue, based on my observations doing that. The smaller app logs always work, pretty much immediately, but the larger apps logs never finish processing.

Attached below is an image showing the network requests to the backend - You can see they successfully send to the backend server, but the issue happens during processing. The large requests never finish processing (have left for more than 24hrs)
due to a Postgres error of unexpected EOF on client connection with an open transaction

logs_too_big

And here is a screenshot of the job_log_entries table in Postgres, the red ones are from the big app, the green ones from the small app.
Screenshot 2021-11-09 at 3 14 10 pm

Are these logs too big for XCMetrics or is something else going on here? Do you have any benchmark for the largest parsable file you've managed to process?

Thanks for making this tool and hope we can figure this out so our team can use this tool!

Looking forward to the Web Interface

XCLogParser & XCMetrics is cool idea, the demo shows the graph is pretty.
Is there any plan to integrate the web interface to the XCMetric service? ๐Ÿš€๐Ÿš€๐Ÿš€

Fatal error: No Queues driver configured

We encountered an issue trying to deploy the latest XCMetrics backend docker image via Google Could Run and are unable to resolve it.

Environment:

  • PostgreSQL: v12
  • docker image latest

Env variables are set to

  • XCMETRICS_USE_ASYNC_LOG_PROCESSING="0"
  • XCMETRICS_USE_CLOUDSQL_SOCKET="1"
  • XCMETRICS_CLOUDSQL_CONNECTION_NAME="***"
  • DB_NAME="database name"
  • DB_USER="database user"
  • DB_PASSWORD="***"

Google Could Run docker image start failed

{
"textPayload": "Fatal error: No Queues driver configured. Configure with app.queues.use(...): file Queues/Application+Queues.swift, line 67",
"insertId": "***",
"resource": {
"type": "cloud_run_revision",
"labels": {
"revision_name": "xcmetrics-00004-soz",
"project_id": "***",
"configuration_name": "xcmetrics",
"location": "europe-west1",
"service_name": "xcmetrics"
}
},
"timestamp": "2022-01-27T09:53:07.063545Z",
"labels": {
"instanceId": "***"
},
"logName": "***/logs/run.googleapis.com%2Fstderr",
"receiveTimestamp": "2022-01-27T09:53:07.067705330Z"
}

Any idea what we could be doing wrong?

Adding an option to track the build's branch

Hi!

I would love the ability to know if a build is associated with a specific git branch, as this would help me analyze improvements or regressions in build times which may be coming in on new PRs. Happy to propose an implementation if this is a welcomed addition.

Thanks!

Detect CI environment variable

Most CI system are automatically populating the build environment with a variable CI to indicate that the build is running on a CI system. It would be great if we can automatically detect that variable from the environment instead of passing it to the XCMetrics invocation by hand.

If this is something you think is useful, I would be very happy to open a PR for it.

Docker Image Version Tags

We are deploying XCMetrics to AWS using Elastic Beanstalk to pull the latest docker image from docker hub. At the moment we can only deploy the latest version of XCMetrics as that is the only tag available, but we would like control over which version we deploy.

Could the versions start to be tagged in addition to latest in docker hub so we can control which version we deploy?

Docker Hub Tags: https://hub.docker.com/r/spotify/xcmetrics/tags?page=1&ordering=last_updated

Mandatory 'excludeCI' parameter breaks the Backstage plugin integration.

Hi,

I'm trying to setup XCMetrics with the Backstage plugin. The dashboard loads, showing the build history, but the Builds tab just shows an error.

After inspecting the response, I found the following message
{ "error": true, "reason": "Value required for key 'excludeCI'." }

and the same message in the XCMetrics-backend logs
xcmetrics-backend-xcmetrics-1 | [ WARNING ] Value required for key 'excludeCI'. [request-id: BE19CCEC-338D-4056-84DD-8F9C6A18D4D6]

I was able to work around this by adding "excludeCI": true to the builds/filter request made from the plugin. I'd be happy to submit a fix for this, just not sure if the plugin is out-of-date or if the backend should handle the excludeCI parameter in a different way.

Crash when running the latest docker image

We are seeing a crash happening quite frequently which happens inside the Postgres stack. I am trying to investigate further where this crash is coming from.

The crash log:

0x7f9b8248f97f
0x55e0ea5038df, Swift runtime failure: Unexpectedly found nil while unwrapping an Optional value at /build/.build/checkouts/swift-nio/Sources/NIO/ByteBuffer-core.swift:0
0x55e0ea5038df, static NIO.ByteBuffer._Storage.(allocateAndPrepareRawMemory in _243B594EFDF92ACEC7911DAF9CEF250E)(bytes: Swift.UInt32, allocator: NIO.ByteBufferAllocator) -> Swift.UnsafeMutableRawPointer at /build/.build/checkouts/swift-nio/Sources/NIO/ByteBuffer-core.swift:243
0x55e0ea5038df, NIO.ByteBuffer._Storage.(allocateStorage in _243B594EFDF92ACEC7911DAF9CEF250E)(capacity: Swift.UInt32) -> NIO.ByteBuffer._Storage at /build/.build/checkouts/swift-nio/Sources/NIO/ByteBuffer-core.swift:255
0x55e0ea5038df, NIO.ByteBuffer._Storage.allocateStorage() -> NIO.ByteBuffer._Storage at /build/.build/checkouts/swift-nio/Sources/NIO/ByteBuffer-core.swift:250
0x55e0ea5038df, NIO.ByteBuffer.clear() -> () at /build/.build/checkouts/swift-nio/Sources/NIO/ByteBuffer-core.swift:706
0x55e0ea52983d, NIO.MessageToByteHandler.write(context: NIO.ChannelHandlerContext, data: NIO.NIOAny, promise: Swift.Optional<NIO.EventLoopPromise<()>>) -> () at /build/.build/checkouts/swift-nio/Sources/NIO/Codec.swift:795
0x55e0ea51942f, NIO.ChannelHandlerContext.(invokeWrite in _EEC863903996E9F191EBAFEB0FB0DFDD)(_: NIO.NIOAny, promise: Swift.Optional<NIO.EventLoopPromise<()>>) -> () at /build/.build/checkouts/swift-nio/Sources/NIO/ChannelPipeline.swift:1424
0x55e0ea51b2fd
0x55e0ea7207b3, function signature specialization <Arg[3] = Dead> of generic specialization <PostgresNIO.PostgresRequestHandler> of (extension in PostgresNIO):NIO.ChannelInboundHandler.write(context: NIO.ChannelHandlerContext, items: Swift.Array<A.OutboundOut>, promise: Swift.Optional<NIO.EventLoopPromise<()>>) -> () at /build/.build/checkouts/postgres-nio/Sources/PostgresNIO/Connection/PostgresConnection+Database.swift:120
0x55e0ea71d131, generic specialization <PostgresNIO.PostgresRequestHandler> of (extension in PostgresNIO):NIO.ChannelInboundHandler.write(context: NIO.ChannelHandlerContext, items: Swift.Array<A.OutboundOut>, promise: Swift.Optional<NIO.EventLoopPromise<()>>) -> () at /build/<compiler-generated>:0
0x55e0ea71d131, PostgresNIO.PostgresRequestHandler.write(context: NIO.ChannelHandlerContext, data: NIO.NIOAny, promise: Swift.Optional<NIO.EventLoopPromise<()>>) -> () at /build/.build/checkouts/postgres-nio/Sources/PostgresNIO/Connection/PostgresConnection+Database.swift:94
0x55e0ea51942f, NIO.ChannelHandlerContext.(invokeWrite in _EEC863903996E9F191EBAFEB0FB0DFDD)(_: NIO.NIOAny, promise: Swift.Optional<NIO.EventLoopPromise<()>>) -> () at /build/.build/checkouts/swift-nio/Sources/NIO/ChannelPipeline.swift:1424
0x55e0ea519456, NIO.ChannelHandlerContext.(invokeWrite in _EEC863903996E9F191EBAFEB0FB0DFDD)(_: NIO.NIOAny, promise: Swift.Optional<NIO.EventLoopPromise<()>>) -> () at /build/.build/checkouts/swift-nio/Sources/NIO/ChannelPipeline.swift:1426
0x55e0ea515dd4
0x55e0ea50c8c8
0x55e0ea50c816, protocol witness for NIO.ChannelOutboundInvoker.write(_: NIO.NIOAny, promise: Swift.Optional<NIO.EventLoopPromise<()>>) -> () in conformance NIO.BaseSocketChannel<A1> : NIO.ChannelOutboundInvoker in NIO at /build/<compiler-generated>:0
0x55e0ea511887, function signature specialization <Arg[1] = Dead, Arg[2] = Dead> of (extension in NIO):NIO.ChannelOutboundInvoker.write(_: NIO.NIOAny, file: Swift.StaticString, line: Swift.UInt) -> NIO.EventLoopFuture<()> at /build/.build/checkouts/swift-nio/Sources/NIO/ChannelInvoker.swift:132
0x55e0ea50cb38
0x55e0ea71feca, function signature specialization <Arg[0] = Existential To Protocol Constrained Generic> of PostgresNIO.PostgresConnection.send(_: PostgresNIO.PostgresRequest, logger: Logging.Logger) -> NIO.EventLoopFuture<()> at /build/.build/checkouts/postgres-nio/Sources/PostgresNIO/Connection/PostgresConnection+Database.swift:11
0x55e0ea48d50a, FluentPostgresDriver._FluentPostgresDatabase.send(_: PostgresNIO.PostgresRequest, logger: Logging.Logger) -> NIO.EventLoopFuture<()> at /build/.build/checkouts/fluent-postgres-driver/Sources/FluentPostgresDriver/FluentPostgresDatabase.swift:128
0x55e0ea48d50a, protocol witness for PostgresNIO.PostgresDatabase.send(_: PostgresNIO.PostgresRequest, logger: Logging.Logger) -> NIO.EventLoopFuture<()> in conformance FluentPostgresDriver._FluentPostgresDatabase : PostgresNIO.PostgresDatabase in FluentPostgresDriver at /build/<compiler-generated>:127
0x55e0ea74a0d1, (extension in PostgresNIO):PostgresNIO.PostgresDatabase.query(_: Swift.String, _: Swift.Array<PostgresNIO.PostgresData>, onMetadata: (PostgresNIO.PostgresQueryMetadata) -> (), onRow: (PostgresNIO.PostgresRow) throws -> ()) -> NIO.EventLoopFuture<()> at /build/.build/checkouts/postgres-nio/Sources/PostgresNIO/PostgresDatabase+Query.swift:32
0x55e0ea48bce1, FluentPostgresDriver._FluentPostgresDatabase.execute(query: FluentKit.DatabaseQuery, onOutput: (FluentKit.DatabaseOutput) -> ()) -> NIO.EventLoopFuture<()> at /build/.build/checkouts/fluent-postgres-driver/Sources/FluentPostgresDriver/FluentPostgresDatabase.swift:28
0x55e0ea46bd65, FluentKit.QueryBuilder.run((FluentKit.DatabaseOutput) -> ()) -> NIO.EventLoopFuture<()> at /build/.build/checkouts/fluent-kit/Sources/FluentKit/Query/Builder/QueryBuilder.swift:286
0x55e0ea46c07d, FluentKit.QueryBuilder.run() -> NIO.EventLoopFuture<()> at /build/.build/checkouts/fluent-kit/Sources/FluentKit/Query/Builder/QueryBuilder.swift:201
0x55e0ea46c07d, FluentKit.QueryBuilder.create() -> NIO.EventLoopFuture<()> at /build/.build/checkouts/fluent-kit/Sources/FluentKit/Query/Builder/QueryBuilder.swift:96
0x55e0ea441bb3, closure #3 () -> NIO.EventLoopFuture<()> in (extension in FluentKit):Swift.Collection< where A.Element: FluentKit.Model>.create(on: FluentKit.Database) -> NIO.EventLoopFuture<()> at /build/.build/checkouts/fluent-kit/Sources/FluentKit/Model/Model+CRUD.swift:171
0x55e0e9f45801, reabstraction thunk helper from @escaping @callee_guaranteed () -> (@owned NIO.EventLoopFuture<()>) to @escaping @callee_guaranteed (@in_guaranteed ()) -> (@owned NIO.EventLoopFuture<()>) at /build/<compiler-generated>:0
0x55e0e9f45801, function signature specialization <Arg[2] = Owned To Guaranteed> of function signature specialization <Arg[1] = [Closure Propagated : reabstraction thunk helper from @escaping @callee_guaranteed () -> (@owned NIO.EventLoopFuture<()>) to @escaping @callee_guaranteed (@in_guaranteed ()) -> (@owned NIO.EventLoopFuture<()>), Argument Types : [@escaping @callee_guaranteed () -> (@owned NIO.EventLoopFuture<()>)]> of generic specialization <(), ()> of closure #1 () -> NIO.CallbackList in NIO.EventLoopFuture.flatMap<A>(file: Swift.StaticString, line: Swift.UInt, _: (A) -> NIO.EventLoopFuture<A1>) -> NIO.EventLoopFuture<A1> at /build/<compiler-generated>:0
0x55e0e9f45c7a, function signature specialization <Arg[1] = [Closure Propagated : reabstraction thunk helper from @escaping @callee_guaranteed () -> (@owned NIO.EventLoopFuture<()>) to @escaping @callee_guaranteed (@in_guaranteed ()) -> (@owned NIO.EventLoopFuture<()>), Argument Types : [@escaping @callee_guaranteed () -> (@owned NIO.EventLoopFuture<()>)]> of generic specialization <(), ()> of closure #1 () -> NIO.CallbackList in NIO.EventLoopFuture.flatMap<A>(file: Swift.StaticString, line: Swift.UInt, _: (A) -> NIO.EventLoopFuture<A1>) -> NIO.EventLoopFuture<A1> at /build/<compiler-generated>:0
0x55e0e9f45c7a, function signature specialization <Arg[0] = Dead, Arg[1] = Dead, Arg[3] = Owned To Guaranteed> of function signature specialization <Arg[2] = [Closure Propagated : reabstraction thunk helper from @escaping @callee_guaranteed () -> (@owned NIO.EventLoopFuture<()>) to @escaping @callee_guaranteed (@in_guaranteed ()) -> (@owned NIO.EventLoopFuture<()>), Argument Types : [@escaping @callee_guaranteed () -> (@owned NIO.EventLoopFuture<()>)]> of generic specialization <(), ()> of NIO.EventLoopFuture.flatMap<A>(file: Swift.StaticString, line: Swift.UInt, _: (A) -> NIO.EventLoopFuture<A1>) -> NIO.EventLoopFuture<A1> at /build/<compiler-generated>:0
0x55e0ea43ec8a, function signature specialization <Arg[2] = [Closure Propagated : reabstraction thunk helper from @escaping @callee_guaranteed () -> (@owned NIO.EventLoopFuture<()>) to @escaping @callee_guaranteed (@in_guaranteed ()) -> (@owned NIO.EventLoopFuture<()>), Argument Types : [@escaping @callee_guaranteed () -> (@owned NIO.EventLoopFuture<()>)]> of generic specialization <(), ()> of NIO.EventLoopFuture.flatMap<A>(file: Swift.StaticString, line: Swift.UInt, _: (A) -> NIO.EventLoopFuture<A1>) -> NIO.EventLoopFuture<A1> at /build/<compiler-generated>:0
0x55e0ea43ec8a, (extension in FluentKit):Swift.Collection< where A.Element: FluentKit.Model>.create(on: FluentKit.Database) -> NIO.EventLoopFuture<()> at /build/.build/checkouts/fluent-kit/Sources/FluentKit/Model/Model+CRUD.swift:168
0x55e0eabdbb54, closure #1 () -> NIO.EventLoopFuture<()> in closure #6 (Swift.Array<XCMetricsBackendLib.BuildNote>) -> () in XCMetricsBackendLib.PostgreSQLMetricsRepository.(insert in _E018F61C537BC4C1E5E8249F972C0535)(on: FluentKit.Database, buildMetrics: XCMetricsBackendLib.BuildMetrics) -> NIO.EventLoopFuture<()> at /build/Sources/XCMetricsBackendLib/Common/Repositories/Postgress/PostgreSQLMetricsRepository.swift:174
0x55e0eabdbb54, partial apply forwarder for closure #1 () -> NIO.EventLoopFuture<()> in closure #6 (Swift.Array<XCMetricsBackendLib.BuildNote>) -> () in XCMetricsBackendLib.PostgreSQLMetricsRepository.(insert in _E018F61C537BC4C1E5E8249F972C0535)(on: FluentKit.Database, buildMetrics: XCMetricsBackendLib.BuildMetrics) -> NIO.EventLoopFuture<()> at /build/<compiler-generated>:0
0x55e0eabda580, reabstraction thunk helper from @escaping @callee_guaranteed () -> (@owned NIO.EventLoopFuture<()>) to @escaping @callee_guaranteed (@in_guaranteed ()) -> (@owned NIO.EventLoopFuture<()>) at /build/<compiler-generated>:0
0x55e0eabda580, partial apply forwarder for reabstraction thunk helper from @escaping @callee_guaranteed () -> (@owned NIO.EventLoopFuture<()>) to @escaping @callee_guaranteed (@in_guaranteed ()) -> (@owned NIO.EventLoopFuture<()>) at /build/<compiler-generated>:0
0x55e0e9f52d88, generic specialization <(), ()> of closure #1 () -> NIO.CallbackList in NIO.EventLoopFuture.flatMap<A>(file: Swift.StaticString, line: Swift.UInt, _: (A) -> NIO.EventLoopFuture<A1>) -> NIO.EventLoopFuture<A1> at /build/<compiler-generated>:0
0x55e0ea558673, reabstraction thunk helper from @escaping @callee_guaranteed () -> (@owned NIO.CallbackList) to @escaping @callee_guaranteed () -> (@out NIO.CallbackList) at /build/<compiler-generated>:0
0x55e0ea558673, partial apply forwarder for reabstraction thunk helper from @escaping @callee_guaranteed () -> (@owned NIO.CallbackList) to @escaping @callee_guaranteed () -> (@out NIO.CallbackList) at /build/<compiler-generated>:0
0x55e0ea55cf98
0x55e0ea54710a, reabstraction thunk helper from @escaping @callee_guaranteed () -> (@out NIO.CallbackList) to @escaping @callee_guaranteed () -> (@owned NIO.CallbackList) at /build/<compiler-generated>:0
0x55e0ea54710a, NIO.CallbackList._run() -> () at /build/.build/checkouts/swift-nio/Sources/NIO/EventLoopFuture.swift:108
0x55e0e9f43185, generic specialization <()> of NIO.EventLoopPromise._resolve(value: Swift.Result<A, Swift.Error>) -> () at /build/<compiler-generated>:0
0x55e0ea71cf5d, generic specialization <()> of NIO.EventLoopPromise.succeed(A) -> () at /build/<compiler-generated>:0
0x55e0ea71cf5d, PostgresNIO.PostgresRequestHandler.(_channelRead in _EC8377CE6023773E62AFAEB7D7896A11)(context: NIO.ChannelHandlerContext, data: NIO.NIOAny) throws -> () at /build/.build/checkouts/postgres-nio/Sources/PostgresNIO/Connection/PostgresConnection+Database.swift:74
0x55e0ea71cfcc, PostgresNIO.PostgresRequestHandler.channelRead(context: NIO.ChannelHandlerContext, data: NIO.NIOAny) -> () at /build/.build/checkouts/postgres-nio/Sources/PostgresNIO/Connection/PostgresConnection+Database.swift:81
0x55e0ea519805, NIO.ChannelHandlerContext.(invokeChannelRead in _EEC863903996E9F191EBAFEB0FB0DFDD)(NIO.NIOAny) -> () at /build/.build/checkouts/swift-nio/Sources/NIO/ChannelPipeline.swift:1344
0x55e0ea519823, NIO.ChannelHandlerContext.(invokeChannelRead in _EEC863903996E9F191EBAFEB0FB0DFDD)(NIO.NIOAny) -> () at /build/.build/checkouts/swift-nio/Sources/NIO/ChannelPipeline.swift:1346
0x55e0ea515582, NIO.ChannelHandlerContext.fireChannelRead(NIO.NIOAny) -> () at /build/.build/checkouts/swift-nio/Sources/NIO/ChannelPipeline.swift:1157
0x55e0ea748417, PostgresNIO.PostgresMessageDecoder.decode(context: NIO.ChannelHandlerContext, buffer: inout NIO.ByteBuffer) throws -> NIO.DecodingState at /build/.build/checkouts/postgres-nio/Sources/PostgresNIO/Message/PostgresMessageDecoder.swift:56
0x55e0ea7484bf, protocol witness for NIO.ByteToMessageDecoder.decode(context: NIO.ChannelHandlerContext, buffer: inout NIO.ByteBuffer) throws -> NIO.DecodingState in conformance PostgresNIO.PostgresMessageDecoder : NIO.ByteToMessageDecoder in PostgresNIO at /build/<compiler-generated>:0
0x55e0ea5288c6, closure #1 (inout A, inout NIO.ByteBuffer) throws -> NIO.DecodingState in NIO.ByteToMessageHandler.(decodeLoop in _F2A740607FEBA425AF6F8C49A24C0AD7)(context: NIO.ChannelHandlerContext, decodeMode: NIO.ByteToMessageHandler<A>.(DecodeMode in _F2A740607FEBA425AF6F8C49A24C0AD7)) throws -> NIO.(B2MDBuffer in _F2A740607FEBA425AF6F8C49A24C0AD7).BufferProcessingResult at /build/.build/checkouts/swift-nio/Sources/NIO/Codec.swift:567
0x55e0ea528661, NIO.ByteToMessageHandler.(withNextBuffer in _F2A740607FEBA425AF6F8C49A24C0AD7)(allowEmptyBuffer: Swift.Bool, _: (inout A, inout NIO.ByteBuffer) throws -> NIO.DecodingState) throws -> NIO.(B2MDBuffer in _F2A740607FEBA425AF6F8C49A24C0AD7).BufferProcessingResult at /build/.build/checkouts/swift-nio/Sources/NIO/Codec.swift:529
0x55e0ea528661, NIO.ByteToMessageHandler.(decodeLoop in _F2A740607FEBA425AF6F8C49A24C0AD7)(context: NIO.ChannelHandlerContext, decodeMode: NIO.ByteToMessageHandler<A>.(DecodeMode in _F2A740607FEBA425AF6F8C49A24C0AD7)) throws -> NIO.(B2MDBuffer in _F2A740607FEBA425AF6F8C49A24C0AD7).BufferProcessingResult at /build/.build/checkouts/swift-nio/Sources/NIO/Codec.swift:563
0x55e0ea528e86, NIO.ByteToMessageHandler.channelRead(context: NIO.ChannelHandlerContext, data: NIO.NIOAny) -> () at /build/.build/checkouts/swift-nio/Sources/NIO/Codec.swift:636
0x55e0ea519805, NIO.ChannelHandlerContext.(invokeChannelRead in _EEC863903996E9F191EBAFEB0FB0DFDD)(NIO.NIOAny) -> () at /build/.build/checkouts/swift-nio/Sources/NIO/ChannelPipeline.swift:1344
0x55e0ea4f436e, NIO.ChannelPipeline.fireChannelRead0(NIO.NIOAny) -> () at .build/checkouts/swift-nio/Sources/NIO/ChannelPipeline.swift:834
0x55e0ea4f436e, NIO.BaseStreamSocketChannel.readFromSocket() throws -> NIO.BaseSocketChannel<A>.ReadResult at /build/.build/checkouts/swift-nio/Sources/NIO/BaseStreamSocketChannel.swift:107
0x55e0ea5807d3
0x55e0ea5897b3, generic specialization <NIO.Socket> of NIO.BaseSocketChannel.readable() -> () at .build/checkouts/swift-nio/Sources/NIO/BaseSocketChannel.swift:1044
0x55e0ea5897b3, inlined generic function <NIO.Socket> of protocol witness for NIO.SelectableChannel.readable() -> () in conformance NIO.BaseSocketChannel<A> : NIO.SelectableChannel in NIO at /build/<compiler-generated>:1041
0x55e0ea5897b3, function signature specialization <Arg[2] = Dead> of generic specialization <NIO.SocketChannel> of NIO.SelectableEventLoop.handleEvent<A where A: NIO.SelectableChannel>(_: NIO.SelectorEventSet, channel: A) -> () at /build/.build/checkouts/swift-nio/Sources/NIO/SelectableEventLoop.swift:328
0x55e0ea588973, reabstraction thunk helper from @callee_guaranteed (@guaranteed NIO.SelectorEvent<NIO.NIORegistration>) -> (@error @owned Swift.Error) to @escaping @callee_guaranteed (@in_guaranteed NIO.SelectorEvent<NIO.NIORegistration>) -> (@error @owned Swift.Error) at /build/<compiler-generated>:0
0x55e0ea588973, partial apply forwarder for reabstraction thunk helper from @callee_guaranteed (@guaranteed NIO.SelectorEvent<NIO.NIORegistration>) -> (@error @owned Swift.Error) to @escaping @callee_guaranteed (@in_guaranteed NIO.SelectorEvent<NIO.NIORegistration>) -> (@error @owned Swift.Error) at /build/<compiler-generated>:0
0x55e0ea58c51c, NIO.Selector.whenReady(strategy: NIO.SelectorStrategy, _: (NIO.SelectorEvent<A>) throws -> ()) throws -> () at /build/.build/checkouts/swift-nio/Sources/NIO/Selector.swift:637
0x55e0ea5850d9, closure #2 () throws -> () in NIO.SelectableEventLoop.run() throws -> () at /build/.build/checkouts/swift-nio/Sources/NIO/SelectableEventLoop.swift:400
0x55e0ea5850d9, reabstraction thunk helper from @callee_guaranteed () -> (@error @owned Swift.Error) to @escaping @callee_guaranteed () -> (@out (), @error @owned Swift.Error) at /build/<compiler-generated>:0
0x55e0ea5850d9, generic specialization <()> of NIO.withAutoReleasePool<A>(() throws -> A) throws -> A at /build/.build/checkouts/swift-nio/Sources/NIO/SelectableEventLoop.swift:26
0x55e0ea5850d9, NIO.SelectableEventLoop.run() throws -> () at /build/.build/checkouts/swift-nio/Sources/NIO/SelectableEventLoop.swift:399
0x55e0ea53d69b, static NIO.MultiThreadedEventLoopGroup.(runTheLoop in _D5D78C61B22284700B9BD1ACFBC25157)(thread: NIO.NIOThread, canEventLoopBeShutdownIndividually: Swift.Bool, selectorFactory: () throws -> NIO.Selector<NIO.NIORegistration>, initializer: (NIO.NIOThread) -> (), _: (NIO.SelectableEventLoop) -> ()) -> () at /build/.build/checkouts/swift-nio/Sources/NIO/EventLoop.swift:838
0x55e0ea53d69b, closure #1 (NIO.NIOThread) -> () in static NIO.MultiThreadedEventLoopGroup.(setupThreadAndEventLoop in _D5D78C61B22284700B9BD1ACFBC25157)(name: Swift.String, selectorFactory: () throws -> NIO.Selector<NIO.NIORegistration>, initializer: (NIO.NIOThread) -> ()) -> NIO.SelectableEventLoop at /build/.build/checkouts/swift-nio/Sources/NIO/EventLoop.swift:858
0x55e0ea542029, partial apply forwarder for closure #1 (NIO.NIOThread) -> () in static NIO.MultiThreadedEventLoopGroup.(setupThreadAndEventLoop in _D5D78C61B22284700B9BD1ACFBC25157)(name: Swift.String, selectorFactory: () throws -> NIO.Selector<NIO.NIORegistration>, initializer: (NIO.NIOThread) -> ()) -> NIO.SelectableEventLoop at /build/<compiler-generated>:0
0x55e0ea5a3d9e, reabstraction thunk helper from @escaping @callee_guaranteed (@guaranteed NIO.NIOThread) -> () to @escaping @callee_guaranteed (@in_guaranteed NIO.NIOThread) -> (@out ()) at /build/<compiler-generated>:0
0x55e0ea542040, partial apply forwarder for reabstraction thunk helper from @escaping @callee_guaranteed (@guaranteed NIO.NIOThread) -> () to @escaping @callee_guaranteed (@in_guaranteed NIO.NIOThread) -> (@out ()) at /build/<compiler-generated>:0
0x55e0ea5a4d56, closure #1 (Swift.Optional<Swift.UnsafeMutableRawPointer>) -> Swift.Optional<Swift.UnsafeMutableRawPointer> in static NIO.ThreadOpsPosix.run(handle: inout Swift.Optional<Swift.UInt>, args: NIO.Box<(body: (NIO.NIOThread) -> (), name: Swift.Optional<Swift.String>)>, detachThread: Swift.Bool) -> () at /build/.build/checkouts/swift-nio/Sources/NIO/ThreadPosix.swift:105
0x7f9b824846da
0x7f9b8068f71e
0xffffffffffffffff

Where the enqueued daily statistics job are started?

I am trying get values from DailyStatisticsJob at /v1/statistics/build/count?days=14 but the statistics_day_build_time table is empty. And while debugging the XCMetricsBackendLib/Config/configure.swift there isn't a call to startScheduledJobs() or similar across the project.

I am missing where it is being called? Or there is other way to start the scheduled jobs?

Plugin for measuring unit test time

Hi all,

Thank you for this awesome project โค๏ธ

We are investigating it and we want to integrate it in order to measure our build times.

I wander do you have any plugins for measuring unit test timing (I'm talking about each test execution time)?
Do you consider viable option to add a plugin for measuring unit test timing or you think it's not related to this project ?

Slow database because of lots of data records?

Hey guys,
so I have been working now with XCMetrics for quite so long and it shows lots of great data that we need, the problem now that we are mapping the data into grafana board to monitor our build times. The problem now is that the postgres database whenever more data is there, the slowest the query to map data is.

especially build_steps and build_targets tables, they are super slow even opening the table and sorting by day asc

I am not sure if there is some problem to that? other than for example deleting old data?

Thank you

XCMetrics support Redis running in cluster mode

Hello Team,

I hope this message finds you well. We would like to utilize XCMetrics for our observing metrics.
Recently, we came across a situation where we wanted to use a Redis instance running in cluster mode. However, we encountered an issue related to handling multi-key operations when interacting with a cluster mode enabled Redis instance, specifically the CROSSSLOT Keys in request don't hash to the same slot error.
We understand that this issue arises due to certain commands trying to access keys stored in different slots, which is not allowed in a Redis cluster setup. It would be beneficial if XCMetrics could natively support Redis running in cluster mode, especially when dealing with larger datasets or higher throughput.
We believe this would be a significant enhancement to XCMetrics, not only benefiting us but also other users who require the improved capabilities that a Redis cluster provides.
We appreciate your considering this enhancement and look forward to your feedback.
Thank you for your tremendous work on XCMetrics.

Best Regards,
Adele

Broken for Xcode 15.3?

I can't see any builds in the XCMetrics database since we updated from Xcode 15.1 to Xcode 15.3. I assume XCMetrics is not compatible with Xcode 15.3. Could that be the problem?

How to retain only the most basic and core data? Such as build time/cpu/memory, full/incremental compilation and other data.

Hi, guys
We have an iOS project with millions of lines and more than 6000+ warning messages. Each compilation will generate a lot of logs. I tried compiling locally several times and generated more than 300M of data. We have dozens of iOS members and if they will all Uploading this data every time to the server will generate a lot of traffic and storage pressure.

Therefore, I want to know if there is any way for us to record only the most basic and core data, such as build time/cpu/memory, full/incremental compilation and other data.
Discarding overly detailed data such as each step/warning information will greatly reduce and save the pressure on the deployed server.

In addition, the .xcactivitylog file exceeds 20MB and uploading will be time-consuming. Do we have any compression solution?

image

That's just about one-tenth of the traffic, which is already so much.
image

Differentiate between RichNotificationExtension and Main target builds

Hello,

When querying XCMetrics for the main target app build time I have also the build time for the RichNotificationExtension. When doing median calculation it makes the results flaky as the extension takes a lot less time to build.

Is there a way to differentiate those two? Do you have suggestion on how to workaround that issue?

On our CI we are using a cloud based provider and it seems that the machine name is changing for each pipeline, so by aggregating first by machine name I get coherent results. But this solution won't work for local developer machines. Furthermore, as we are monitoring success builds for the same build I can have the main app succeeding but the extension failing and it will not be a failed build.

Thank you very much

What is `for Previews _scheme-name_` in `builds` table.

We recently added XCMetrics to tou our project. When looking into the database I can see a set of rows in the builds table with the scheme name for Previews _original-scheme-name_. And the duration fo these builds are so high.

From where these for Previews * builds are coming?

Example screenhot
Screenshot 2023-09-18 at 19 22 44

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.