Skip to content

Specify log file through API #250

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 9, 2018
Merged

Specify log file through API #250

merged 5 commits into from
May 9, 2018

Conversation

dianpopa
Copy link
Contributor

@dianpopa dianpopa commented May 4, 2018

Changes

  • users can now attach a log path through an API call
  • the logger is thread safe
  • added unit tests for all the newly added functions

Testing

Build Time

Prerequisite

## add the necessary musl target to the active toolchain
rustup target add x86_64-unknown-linux-musl

Build tests

cargo fmt —all
cargo build # no warning
cargo build —release
sudo env "PATH=$PATH" cargo test --all
sudo env "PATH=$PATH" cargo kcov —all

Coverage report for logger related files

File Coverage %
api_server/src/request/sync/logger.rs 96.2
vmm/src/logger_config.rs 97.2
logger/src/error.rs 91.7
logger/src/writers.rs 94.1
logger/src/lib.rs 95.7

Integration Testing

rm -f /tmp/firecracker.socket && \
target/x86_64-unknown-linux-musl/debug/firecracker --api-sock=/tmp/firecracker.socket
  1. in another console start sending some logger-related curl requests for starting basic firecracker guest
# should return error as the log path is an empty one
curl --unix-socket /tmp/firecracker.socket -i \
     -X PUT "http://localhost/logger" \
     -H "accept: application/json" \
     -H "Content-Type: application/json" \
     -d "{ 
            \"path\": \"\", 
            \"level\": \"Info\", 
            \"show_level\": true, 
            \"show_log_origin\": true
         }"
# Output
HTTP/1.1 400 Bad Request
Content-Type: application/json
Transfer-Encoding: chunked
Date: Fri, 04 May 2018 14:25:38 GMT

{
  "fault_message": "Cannot initialize logging system! Failed to create log file. Error: entity not found"
}
  1. set a valid local log_path
export log_path=tmp.log
curl --unix-socket /tmp/firecracker.socket -i      -X PUT "http://localhost/logger"      -H "accept: application/json"      -H "Content-Type: application/json"      -d "{ 
            \"path\": \"${log_path}\", 
            \"level\": \"Info\", 
            \"show_level\": true, 
            \"show_log_origin\": true
         }"
# Output:
HTTP/1.1 201 Created
Content-Length: 0
Date: Fri, 04 May 2018 14:26:40 GMT
  1. try to initialize the logger a second time. Should output:
HTTP/1.1 400 Bad Request
Content-Type: application/json
Transfer-Encoding: chunked
Date: Fri, 04 May 2018 14:29:05 GMT

{
  "fault_message": "Cannot initialize logging system! Reinitialization of logger not allowed."
}
  1. now try to boot up a machine:
curl --unix-socket /tmp/firecracker.socket -i  \
     -X PUT "http://localhost/boot-source" \
     -H "accept: application/json" \
     -H "Content-Type: application/json" \
     -d "{ 
           \"boot_source_id\": \"alinux_kernel\",
           \"source_type\": \"LocalImage\", 
           \"local_image\": 
                { 
                    \"kernel_image_path\": \"${kernel_path}\" 
                }
        }"

curl --unix-socket /tmp/firecracker.socket -i \
     -X PUT "http://localhost/machine-config" \
     -H "accept: application/json" \
     -H "Content-Type: application/json" \
     -d "{ \"vcpu_count\": 4, \"mem_size_mib\": 256}"

# Add root block device
curl --unix-socket /tmp/firecracker.socket -i \
     -X PUT "http://localhost/drives/root" \
     -H "accept: application/json" \
     -H "Content-Type: application/json" \
     -d "{ 
            \"drive_id\": \"root\",
            \"path_on_host\": \"${rootfs_path}\", 
            \"is_root_device\": true, 
            \"permissions\": \"rw\", 
            \"state\": \"Attached\"
         }"

curl --unix-socket /tmp/firecracker.socket -i \
     -X PUT "http://localhost/actions/start" \
     -H  "accept: application/json" \
     -H  "Content-Type: application/json" \
     -d "{  
            \"action_id\": \"start\",  
            \"action_type\": \"InstanceStart\"
         }"

# Get the response of starting the instance
curl --unix-socket /tmp/firecracker.socket -i \
     -X GET "http://localhost/actions/start" \
     -H "accept: application/json"

sudo ip link delete vmtap33
  1. in the initial console the guest should start up
# login: ...
# reboot
  1. now check that the file tmp.log contains the expected output
vim tmp.log
# it should contain 
# [INFO:vmm/src/lib.rs:810] vcpu requested shutdown
  1. let s also test that the configuration does not fail
    • kill the firecracker process and do the 0. step again
    • set the show_log_origin to false
exprot log_path=tmp.log
curl --unix-socket /tmp/firecracker.socket -i      -X PUT "http://localhost/logger"      -H "accept: application/json"      -H "Content-Type: application/json"      -d "{ 
            \"path\": \"${log_path}\", 
            \"level\": \"Info\", 
            \"show_level\": true, 
            \"show_log_origin\": false
         }"
# Output:
HTTP/1.1 201 Created
Content-Length: 0
Date: Fri, 04 May 2018 14:26:40 GMT
* send commands from 4.
* reboot machine
* check again the tmp.log file. should now contain no file path and line number:
[INFO] vcpu requested shutdown

@dianpopa dianpopa requested a review from a team May 4, 2018 14:31
@dianpopa dianpopa self-assigned this May 4, 2018
assert!(&desc.into_parsed_request().is_ok());
// I will test this when the other unit tests are merged
//let (sender, receiver) = oneshot::channel();
//assert!(&desc.into_parsed_request().eq(&Ok(ParsedRequest::Sync(SyncRequest::PutLogger(desc, sender), receiver))));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order for this to work, you need to implement the use case for PutLogger in impl PartialEq for SyncRequest.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks for the hint.


static INIT: Once = ONCE_INIT;
static mut INIT_RES: Result<usize> = Ok(UNINITIALIZED);
//static INIT: Once = ONCE_INIT;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If INIT isn't needed any more, please remove it instead of commenting it out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

INIT_RES = Err(LoggerError::NeverInitialized(format!("{}", e)))
Err(ref e) => {
STATE.store(UNINITIALIZED, Ordering::SeqCst);
return Err(LoggerError::NeverInitialized(format!("{}", e)));
Copy link

@alxiord alxiord May 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cosmetic concern: the error e is propagated all the way up from libstd::io::File::create and is one of libstd::io::error::ErrorKind, the string representations of which are all lowercase. So the error message (as seen in the tests run) looks like

{
  "fault_message": "Cannot initialize logging system! Failed to create log file. entity not found"
}

Can you please make the error message something like Failed to create log file. Error: <propagated error> ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solved it; Take a look at error.rs in impl fmt::Display for LoggerError.

vmm/src/lib.rs Outdated
}
}
SyncRequest::PutLogger(logger_description, sender) => {
eprintln!(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this for debugging purposes only?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mistakenly left it there. I removed it now.

@alxiord alxiord changed the title Spcecify log file through API Specify log file through API May 4, 2018
description:
Describes the configuration option for the logger intitialization.
properties:
source_type:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This field is not necessary. Just use the path like all other resources currently do. When we move to FD passing, we will change all API calls from using path to using FDs.
I believe this field will never be used so I suggest removing it.

Copy link
Contributor Author

@dianpopa dianpopa May 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you confident that we will only support FD passing? Why not keep around both versions?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am confident we will not support both versions at the same time 😃

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hehe :) I will do the change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, take a look please

@@ -143,6 +143,29 @@ paths:
schema:
$ref: "#/definitions/Error"

/logger:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add these to firecracker-v1.0.yaml as well.

Copy link
Member

@andreeaflorescu andreeaflorescu May 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed about it yesterday. firecracker-v1.0.yaml is very outdated. So we have here two possibilities: either update it to match what we have now in firecracker-beta, or we don't update it at all for now and only use it as a " What the future looks like" yaml. Since we are sort of time bound, I suggest we don't update it for now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

@@ -258,6 +277,8 @@ fn parse_request<'a>(
method,
path,
str::from_utf8(body.as_ref()).unwrap()
// when time will come, we could better do
serde_json::from_slice(&body).unwrap()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uncommenting this debug block breaks compilation with this change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know. I left it there to consider it as an option 'when time will come'. Do we want me to remove it or solve the compilation errors?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's more of a nit, you could leave it as is, but I would add '//' to it so that the code still works when uncommenting the whole block.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a comment.


type Result<T> = result::Result<T, APILoggerError>;

pub fn init_logger(api_logger: APILoggerDescription) -> Result<()> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally you could've/should've used the new API<->VMM model that uses common data structs for both api_server and vmm.
This new model is the one proposed in @andreeaflorescu 's PR #248 in the data_model crate.

The code here looks very good and I'm personally fine with merging it, but do have a look at the aforementioned PR and decide for yourself.

Copy link
Contributor Author

@dianpopa dianpopa May 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, if you take a closer look you will see that logger_config does not redefine any type; What #248 wants is to remove the necessity to redefine types inside vmm, which in my case does not happen.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

"{:?}",
LoggerError::Poisoned(String::from("Never Initialized"))
).contains("Poisoned")
println!(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we want to print all of these (all the println!s in this test) during unit tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to increase coverage; this prints are the ones that exercise the Debug trait.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They exercise, but don't check anything thus giving us false coverage.
Without proper checking we could break something and unittests and coverage will still look good.

I suggest you find a way to actually check the Debug trait output, or otherwise remove this and leave it without coverage.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, take a look.

acatangiu
acatangiu previously approved these changes May 8, 2018
dianpopa added 5 commits May 9, 2018 04:47
through an API call.

Signed-off-by: Diana Popa <[email protected]>
* removed static variable for keeping status
* used AtomicSize for safely sharing state between threads
* appended relevant error on top of the low level one
* removed Poison status error as it stopped us from being able
to try reinitialization

Signed-off-by: Diana Popa <[email protected]>
* call asserts on the last code in the test_init
* exercise Display for the LoggerError

Signed-off-by: Diana Popa <[email protected]>
inside the vmm as an intermediate step in the
logger setup triggered by the API.

Signed-off-by: Diana Popa <[email protected]>
@acatangiu acatangiu merged commit 17dfb1f into firecracker-microvm:master May 9, 2018
@dianpopa dianpopa deleted the i143 branch June 13, 2018 10:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants