Skip to content

Commit ec6d40c

Browse files
authored
Merge pull request #2770 from fermyon/fix-logging
[Factors] Fix logging
2 parents c6ad6b5 + d5ea75a commit ec6d40c

File tree

2 files changed

+71
-15
lines changed

2 files changed

+71
-15
lines changed

crates/runtime-config/src/lib.rs

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ pub struct ResolvedRuntimeConfig<T> {
3838
///
3939
/// `None` is used for an "unset" state directory which each factor will treat differently.
4040
pub state_dir: Option<PathBuf>,
41+
/// The fully resolved log directory.
42+
///
43+
/// `None` is used for an "unset" log directory.
44+
pub log_dir: Option<PathBuf>,
4145
}
4246

4347
impl<T> ResolvedRuntimeConfig<T>
@@ -49,13 +53,23 @@ where
4953
pub fn from_optional_file(
5054
runtime_config_path: Option<&Path>,
5155
provided_state_dir: Option<&Path>,
56+
provided_log_dir: LogDir,
5257
use_gpu: bool,
5358
) -> anyhow::Result<Self> {
5459
match runtime_config_path {
55-
Some(runtime_config_path) => {
56-
Self::from_file(runtime_config_path, provided_state_dir, use_gpu)
57-
}
58-
None => Self::new(Default::default(), None, provided_state_dir, use_gpu),
60+
Some(runtime_config_path) => Self::from_file(
61+
runtime_config_path,
62+
provided_state_dir,
63+
provided_log_dir,
64+
use_gpu,
65+
),
66+
None => Self::new(
67+
Default::default(),
68+
None,
69+
provided_state_dir,
70+
provided_log_dir,
71+
use_gpu,
72+
),
5973
}
6074
}
6175

@@ -65,6 +79,7 @@ where
6579
pub fn from_file(
6680
runtime_config_path: &Path,
6781
provided_state_dir: Option<&Path>,
82+
provided_log_dir: LogDir,
6883
use_gpu: bool,
6984
) -> anyhow::Result<Self> {
7085
let file = std::fs::read_to_string(runtime_config_path).with_context(|| {
@@ -80,17 +95,24 @@ where
8095
)
8196
})?;
8297

83-
Self::new(toml, Some(runtime_config_path), provided_state_dir, use_gpu)
98+
Self::new(
99+
toml,
100+
Some(runtime_config_path),
101+
provided_state_dir,
102+
provided_log_dir,
103+
use_gpu,
104+
)
84105
}
85106

86107
/// Creates a new resolved runtime configuration from a TOML table.
87108
pub fn new(
88109
toml: toml::Table,
89110
runtime_config_path: Option<&Path>,
90111
provided_state_dir: Option<&Path>,
112+
provided_log_dir: LogDir,
91113
use_gpu: bool,
92114
) -> anyhow::Result<Self> {
93-
let toml_resolver = TomlResolver::new(&toml, provided_state_dir);
115+
let toml_resolver = TomlResolver::new(&toml, provided_state_dir, provided_log_dir);
94116
let tls_resolver = runtime_config_path.map(SpinTlsRuntimeConfig::new);
95117
let key_value_config_resolver = key_value_config_resolver(toml_resolver.state_dir()?);
96118
let sqlite_config_resolver = sqlite_config_resolver(toml_resolver.state_dir()?)
@@ -110,6 +132,7 @@ where
110132
key_value_resolver: key_value_config_resolver,
111133
sqlite_resolver: sqlite_config_resolver,
112134
state_dir: toml_resolver.state_dir()?,
135+
log_dir: toml_resolver.log_dir()?,
113136
})
114137
}
115138

@@ -144,6 +167,11 @@ where
144167
pub fn state_dir(&self) -> Option<PathBuf> {
145168
self.state_dir.clone()
146169
}
170+
171+
/// The fully resolved state directory.
172+
pub fn log_dir(&self) -> Option<PathBuf> {
173+
self.log_dir.clone()
174+
}
147175
}
148176

149177
#[derive(Clone, Debug)]
@@ -152,16 +180,19 @@ pub struct TomlResolver<'a> {
152180
table: TomlKeyTracker<'a>,
153181
/// Explicitly provided state directory.
154182
state_dir: Option<&'a Path>,
183+
/// Explicitly provided log directory.
184+
log_dir: LogDir,
155185
}
156186

157187
impl<'a> TomlResolver<'a> {
158188
/// Create a new TOML resolver.
159189
///
160190
/// The `state_dir` is the explicitly provided state directory, if any.
161-
pub fn new(table: &'a toml::Table, state_dir: Option<&'a Path>) -> Self {
191+
pub fn new(table: &'a toml::Table, state_dir: Option<&'a Path>, log_dir: LogDir) -> Self {
162192
Self {
163193
table: TomlKeyTracker::new(table),
164194
state_dir,
195+
log_dir,
165196
}
166197
}
167198

@@ -183,6 +214,17 @@ impl<'a> TomlResolver<'a> {
183214
.transpose()
184215
}
185216

217+
/// Get the configured log directory.
218+
///
219+
/// Errors if the path cannot be converted to an absolute path.
220+
pub fn log_dir(&self) -> std::io::Result<Option<PathBuf>> {
221+
match &self.log_dir {
222+
LogDir::Provided(p) => Ok(Some(std::path::absolute(p)?)),
223+
LogDir::Default => Ok(self.state_dir()?.map(|p| p.join("logs"))),
224+
LogDir::None => Ok(None),
225+
}
226+
}
227+
186228
/// Validate that all keys in the TOML file have been used.
187229
pub fn validate_all_keys_used(&self) -> spin_factors::Result<()> {
188230
self.table.validate_all_keys_used()
@@ -354,3 +396,14 @@ fn sqlite_config_resolver(
354396
local_database_dir,
355397
))
356398
}
399+
400+
/// The log directory for the trigger.
401+
#[derive(Clone, Debug)]
402+
pub enum LogDir {
403+
/// Use the explicitly provided log directory.
404+
Provided(PathBuf),
405+
/// Use the default log directory.
406+
Default,
407+
/// Do not log.
408+
None,
409+
}

crates/trigger/src/cli.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use spin_common::ui::quoted_path;
1010
use spin_common::url::parse_file_url;
1111
use spin_common::{arg_parser::parse_kv, sloth};
1212
use spin_factors_executor::{ComponentLoader, FactorsExecutor};
13-
use spin_runtime_config::ResolvedRuntimeConfig;
13+
use spin_runtime_config::{LogDir, ResolvedRuntimeConfig};
1414

1515
use crate::factors::{TriggerFactors, TriggerFactorsRuntimeConfig};
1616
use crate::stdio::{FollowComponents, StdioLoggingExecutorHooks};
@@ -317,17 +317,25 @@ impl<T: Trigger> TriggerAppBuilder<T> {
317317
// Default to `.spin/` in the local app dir
318318
None => options.local_app_dir.map(|d| Path::new(d).join(".spin")),
319319
};
320+
let log_dir = match &options.log_dir {
321+
// Make sure `--log-dir=""` unsets the log dir
322+
Some(p) if p.as_os_str().is_empty() => LogDir::None,
323+
Some(p) => LogDir::Provided(p.clone()),
324+
None => LogDir::Default,
325+
};
320326
let runtime_config =
321327
ResolvedRuntimeConfig::<TriggerFactorsRuntimeConfig>::from_optional_file(
322328
options.runtime_config_file,
323329
state_dir.as_deref(),
330+
log_dir,
324331
use_gpu,
325332
)?;
326333

327334
runtime_config
328335
.set_initial_key_values(&options.initial_key_values)
329336
.await?;
330337

338+
let log_dir = runtime_config.log_dir();
331339
let factors = TriggerFactors::new(
332340
runtime_config.state_dir(),
333341
self.working_dir.clone(),
@@ -338,12 +346,7 @@ impl<T: Trigger> TriggerAppBuilder<T> {
338346
)
339347
.context("failed to create factors")?;
340348

341-
// TODO: move these into Factor methods/constructors
342-
// let init_data = crate::HostComponentInitData::new(
343-
// &*self.key_values,
344-
// &*self.sqlite_statements,
345-
// LLmOptions { use_gpu: true },
346-
// );
349+
// TODO(factors): handle: self.sqlite_statements
347350

348351
// TODO: port the rest of the component loader logic
349352
struct SimpleComponentLoader;
@@ -377,7 +380,7 @@ impl<T: Trigger> TriggerAppBuilder<T> {
377380

378381
executor.add_hooks(StdioLoggingExecutorHooks::new(
379382
options.follow_components,
380-
options.log_dir,
383+
log_dir,
381384
));
382385
// TODO:
383386
// builder.hooks(SummariseRuntimeConfigHook::new(&self.runtime_config_file));

0 commit comments

Comments
 (0)