$30 off During Our Annual Pro Sale. View Details »

Rust at Sentry

Rust at Sentry

An introduction to how we use Rust at Sentry.

Armin Ronacher

July 07, 2017
Tweet

More Decks by Armin Ronacher

Other Decks in Programming

Transcript

  1. Rust at Sentry
    Armin @mitsuhiko Ronacher

    View Slide

  2. Hi, I'm Armin
    ... and I do Open Source,
    lots of Python and SaaS
    Flask
    Sentry

    View Slide

  3. … and here is
    where you
    can find me
    twitter.com/@mitsuhiko
    github.com/mitsuhiko
    lucumr.pocoo.org/

    View Slide

  4. 800°C
    36° 2' 0.4662" N
    118° 15' 38.7792" W
    795°C
    789°C
    797°C
    793°C
    805°C
    782°C
    we show you
    your crashes

    View Slide

  5. View Slide

  6. View Slide

  7. a bit about us
    chapter 0

    View Slide

  8. Open Source Project
    “sentry”

    View Slide

  9. Cloud Hosted
    “sentry.io”

    View Slide

  10. relatively flexible stack
    postgres, mysql, cassandra, riak, …

    View Slide

  11. our general tech stack
    chapter 1

    View Slide

  12. Lots of Python

    View Slide

  13. Simple Stack
    Python
    RabbitMQ
    Postgres
    Riak
    Redis

    View Slide

  14. Conservative Approach
    to Adding New Systems

    View Slide

  15. prefer Internal Modularity
    over
    building More Services

    View Slide

  16. how does rust fit?

    View Slide

  17. why is there Rust?
    chapter 2

    View Slide

  18. a bit of a hobby of mine

    View Slide

  19. turned into sentry-cli
    (command line client to manage organizations / build integration)

    View Slide

  20. later reused components
    for Python modules

    View Slide

  21. now part of our tech stack

    View Slide

  22. how we started
    chapter 3

    View Slide

  23. why we use Rust for sentry-cli

    View Slide

  24. $ otool -L which sentry-cli
    /usr/local/bin/sentry-cli:
    /System/Library/Frameworks/Security.framework/Versions/A/Security
    /usr/lib/libiconv.2.dylib
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
    /usr/lib/libcurl.4.dylib
    /usr/lib/libz.1.dylib
    /usr/lib/libSystem.B.dylib

    View Slide

  25. $ curl -sL https://sentry.io/get-cli/ | bash
    $ npm install sentry-cli-binary

    View Slide

  26. that and crates.io

    View Slide

  27. rejected alternatives
    go
    JavaScript (bundled node)
    C / C++
    Python / Ruby

    View Slide

  28. things that work well
    serialization / deserialization
    error handling
    console UX
    file size

    View Slide

  29. from client to server
    chapter 4

    View Slide

  30. View Slide

  31. sourcemap parsing

    View Slide

  32. reused sentry-cli
    code for server

    View Slide

  33. +20 sec -> < 500ms
    processing time

    View Slide

  34. debug symbols

    View Slide

  35. proguard

    View Slide

  36. marrying python and rust
    chapter 5

    View Slide

  37. github.com/mitsuhiko/snaek

    View Slide

  38. from setuptools import setup, find_packages
    setup(
    name='example',
    version='0.0.1',
    packages=find_packages(),
    include_package_data=True,
    zip_safe=False,
    platforms='any',
    install_requires=[
    'snaek',
    ],
    snaek_rust_modules=[
    ('example._native', 'rust/'),
    ]
    )

    View Slide

  39. build rust library
    expose rust -> cabi
    snaek to consume

    View Slide

  40. #[repr(C)]
    pub struct Point {
    pub x: f32,
    pub y: f32,
    }
    #[no_mangle]
    pub unsafe extern "C" fn example_get_origin() -> Point {
    Point { x: 0.0, y: 0.0 }
    }

    View Slide

  41. from example._native import lib
    def get_origin():
    point = lib.example_get_origin()
    return (point.x, point.y)

    View Slide

  42. things in rust to love
    chapter 6

    View Slide

  43. #[derive(Serialize, Deserialize, Debug, Default)]
    pub struct Deploy {
    #[serde(rename="environment")]
    pub env: String,
    pub name: Option,
    pub url: Option,
    #[serde(rename="dateStarted")]
    pub started: Option>,
    #[serde(rename="dateFinished")]
    pub finished: Option>,
    }

    View Slide

  44. /// Lists all deploys for a release
    pub fn list_deploys(&self, org: &str, version: &str)
    -> ApiResult>
    {
    self.get(&format!("/organizations/{}/releases/{}/deploys/",
    PathArg(org), PathArg(version)))?
    .convert()
    }

    View Slide

  45. super flexible
    (de)serialization layer

    View Slide

  46. crates we use / built
    chapter 7

    View Slide

  47. if_chain
    lazy_static
    error-chain
    always useful

    View Slide

  48. serde
    serde_derive
    serde_json
    serde_yaml
    for serialization

    View Slide

  49. console
    indicatif
    dialoguer
    for pretty console UI
    ours :)

    View Slide

  50. rust-curl
    openssl-probe
    HTTP stuff

    View Slide

  51. elementtree
    XML
    ours :)

    View Slide

  52. things we don't like
    chapter 8

    View Slide

  53. compile times :'(

    View Slide

  54. things rust needs
    chapter 9

    View Slide

  55. “what not to do” guide

    View Slide

  56. incremental compilation

    View Slide

  57. higher level C ABI tools

    View Slide

  58. Questions?

    View Slide