# Add logging to hello world

The following guide discusses adding the [Rust Fuchsia logger library](https://fuchsia-docs.firebaseapp.com/rust/fuchsia_syslog/index.html)
to the existing [hello world example](/examples/hello_world/rust/)
component. In this guide, development takes place within the Fuchsia source tree.

With the Fuchsia logger library, you can interact with log collection
services. You can use Fuchsia's logging tools to log and analyze services
and components that are written to run on Fuchsia.


## Prerequisites {#prerequisites}

*   A hardware device that is set up to run Fuchsia.
    *   The device should be paved and running. If you haven't already
        installed Fuchsia, see [Get Started](/docs/getting_started.md).
*   Rust installed on your environment.
    *   The Fuchsia build installs a version of Rust that can be used for
        Fuchsia development. If you have already built Fuchsia, you don't need
        to install Rust again.


## Set build to include example {#include-example}

This guide modifies the existing hello world Rust example component.
In order to run that component later, you must set the hello world component with
the `fx` tool.

Run `fx set`, replacing `PRODUCT` and `BOARD` with your chosen product and board.

<pre class="prettyprint">
    fx set <b>PRODUCT</b>.<b>BOARD</b>  --with //examples/hello_world
</pre>

Note:
To see a list of possible products, run: <p><pre class="prettyprint">fx list-products</pre></p>
To see a list of possible boards, run: <p><pre class="prettyprint">fx list-boards</pre></p>

## Edit the component package {#edit-component-package}

When connecting your component to an additional service, you need to
do the following:

1. [Edit the `BUILD.gn`](#edit-the-buildgn).

1. [Edit the source file containing the `main()`](#edit-the-source-file).

1. [Edit the component manifest](#edit-the-component-manifest).

### Edit the BUILD.gn {#edit-the-buildgn}

You can declare your component's dependencies and source files in the `BUILD.gn`.

For more information, see [Introduction to GN](/docs/concepts/build_system/intro.md).

1.  Open  the `BUILD.gn` in your chosen text editor.

    ```
    vi ~/fuchsia/examples/hello_world/rust/BUILD.gn
    ```

1.  Add `"//src/lib/syslog/rust:syslog"` to the dependencies array in the
   `rustc_binary` target, which defines the executable.

    After adding this dependency, the `rustc_binary` in your `BUILD.gn`  should
    look like this:

    ```
    …
    rustc_binary("bin") {
    name = "hello_world_rust"
    with_unit_tests = true
    edition = "2018"

    deps = [
    "//src/lib/syslog/rust:syslog",
    ]
    test_deps = [ "//garnet/public/rust/fuchsia-async" ]
    }
    …
    ```

### Edit the source file {#edit-the-source-file}

The source files are included in the `src` directory of your component's
package. In this guide, the source file is `main.rs`.

1.  Open  the source file, `main.rs`, with your chosen text editor.

    ```
    vi ~/fuchsia/examples/hello_world/rust/src/main.rs
    ```

1.  Add a `use` declaration for the `fuchsia_syslog` crate.

    ```
    use fuchsia_syslog as syslog
    ```

1.  Within `main()`, initialize the `fuchsia_syslog` crate.

    ```
    syslog::init().expect("should not fail");
    ```

1.  Within `main()`, add your log message.

    ```
    syslog::fx_log_info!("{}, log!", greeting());
    ```

    At this point, `main.rs` should look like this:

    ```rust
    use fuchsia_syslog as syslog;

    fn main() {
        syslog::init().expect("should not fail");
        syslog::fx_log_info!("{}, log!", greeting());
        println!("{}, world!", greeting());
    }
    …
    ```

### Edit the component manifest {#edit-the-component-manifest}

The component manifest is a JSON file with the `.cmx` file extension.

The component manifest declares what services and resources your package uses.

For more information, see [Component manifest](/docs/concepts/storage/component_manifest.md).

1.  Open the component manifest, `hello_world_rust.cmx`, in your chosen
    text editor.

    ```
    vi ~/fuchsia/examples/hello_world/rust/meta/hello_world_rust.cmx
    ```

1.  Add a `sandbox` property with a `services` array.

1.  Include the `fuchsia.logger.LogSink` service within the `services`
    array.

    At this point, `hello_world_rust.cmx` should look like this:

    ```
        {
            "program": {
                "binary": "bin/hello_world_rust"
            },
            "sandbox": {
                "services": [ "fuchsia.logger.LogSink" ]
            }
        }
    ```

1.  Execute a build of the Fuchsia image that contains your modified component
    package.

    ```
    fx build
    ```

### Test logging {#test-logging}

1.  Ensure that `fx serve` is running in a shell tab. If it is not, open
    a shell tab and run `fx serve`.

    ```
    cd ~/fuchsia
    ```

    ```
    fx serve
    ```

1.  In a new shell tab, navigate to your `fuchsia` directory and run `fx log`.

    ```
    cd ~/fuchsia
    ```

    ```
    fx log
    ```

1.  In a new shell tab, navigate to your fuchsia directory and run the
    `hello_world_rust` component:

    ```
    cd ~/fuchsia
    ```

    ```
    fx shell run fuchsia-pkg://fuchsia.com/hello_world_rust#meta/hello_world_rust.cmx
    ```

1.  Navigate to the shell tab where you ran `fx log`.

    You should be able to see your logging text, which in this example is
    `Hello log!`.
