Optimized writing by enlarging the file before the single entries are written
(that saves the file system from starting a new transaction, which is currently expensive). Changed output a bit: the launch line now also contains the parent team ID, file paths are truncated from applications. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13100 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
aadb0f6bb8
commit
fc95358474
@ -35,9 +35,10 @@ struct cache_log {
|
|||||||
union {
|
union {
|
||||||
char file_name[B_FILE_NAME_LENGTH];
|
char file_name[B_FILE_NAME_LENGTH];
|
||||||
struct {
|
struct {
|
||||||
char **array;
|
char **args;
|
||||||
int32 count;
|
int32 arg_count;
|
||||||
} args;
|
team_id parent;
|
||||||
|
} launch;
|
||||||
int32 access_type;
|
int32 access_type;
|
||||||
};
|
};
|
||||||
bigtime_t timestamp;
|
bigtime_t timestamp;
|
||||||
@ -77,7 +78,15 @@ get_log_entry()
|
|||||||
|
|
||||||
struct thread *thread = thread_get_current_thread();
|
struct thread *thread = thread_get_current_thread();
|
||||||
log->team = thread->team->id;
|
log->team = thread->team->id;
|
||||||
strlcpy(log->team_name, thread->team->name, B_OS_NAME_LENGTH);
|
|
||||||
|
// cut off path from name
|
||||||
|
const char *leaf = strrchr(thread->team->name, '/');
|
||||||
|
if (leaf == NULL)
|
||||||
|
leaf = thread->team->name;
|
||||||
|
else
|
||||||
|
leaf++;
|
||||||
|
|
||||||
|
strlcpy(log->team_name, leaf, B_OS_NAME_LENGTH);
|
||||||
|
|
||||||
log->timestamp = system_time();
|
log->timestamp = system_time();
|
||||||
|
|
||||||
@ -147,15 +156,38 @@ log_node_launched(size_t argCount, char * const *args)
|
|||||||
log->action = 'l';
|
log->action = 'l';
|
||||||
log->type = FDTYPE_FILE;
|
log->type = FDTYPE_FILE;
|
||||||
|
|
||||||
log->args.array = (char **)malloc(argCount * sizeof(char *));
|
log->launch.args = (char **)malloc(argCount * sizeof(char *));
|
||||||
log->args.count = argCount;
|
log->launch.arg_count = argCount;
|
||||||
|
|
||||||
for (uint32 i = 0; i < argCount; i++) {
|
for (uint32 i = 0; i < argCount; i++) {
|
||||||
log->args.array[i] = strdup(args[i]);
|
if (i == 0) {
|
||||||
|
// cut off path from parent team name
|
||||||
|
struct team *team = thread_get_current_thread()->team;
|
||||||
|
char name[B_OS_NAME_LENGTH];
|
||||||
|
cpu_status state;
|
||||||
|
|
||||||
|
state = disable_interrupts();
|
||||||
|
GRAB_TEAM_LOCK();
|
||||||
|
|
||||||
|
log->launch.parent = team->parent->id;
|
||||||
|
strlcpy(name, team->parent->name, B_OS_NAME_LENGTH);
|
||||||
|
|
||||||
|
RELEASE_TEAM_LOCK();
|
||||||
|
restore_interrupts(state);
|
||||||
|
|
||||||
|
const char *leaf = strrchr(name, '/');
|
||||||
|
if (leaf == NULL)
|
||||||
|
leaf = name;
|
||||||
|
else
|
||||||
|
leaf++;
|
||||||
|
|
||||||
|
log->launch.args[0] = strdup(leaf);
|
||||||
|
} else
|
||||||
|
log->launch.args[i] = strdup(args[i]);
|
||||||
|
|
||||||
// remove newlines from the arguments
|
// remove newlines from the arguments
|
||||||
char *newline;
|
char *newline;
|
||||||
while ((newline = strchr(log->args.array[i], '\n')) != NULL) {
|
while ((newline = strchr(log->launch.args[i], '\n')) != NULL) {
|
||||||
*newline = ' ';
|
*newline = ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,6 +204,15 @@ log_writer_daemon(void *arg, int /*iteration*/)
|
|||||||
mutex_lock(&sLock);
|
mutex_lock(&sLock);
|
||||||
|
|
||||||
if (sCurrentEntry > kLogWriteThreshold || arg != NULL) {
|
if (sCurrentEntry > kLogWriteThreshold || arg != NULL) {
|
||||||
|
off_t fileSize = 0;
|
||||||
|
struct stat stat;
|
||||||
|
if (fstat(sLogFile, &stat) == 0) {
|
||||||
|
// enlarge file, so that it can be written faster
|
||||||
|
fileSize = stat.st_size;
|
||||||
|
ftruncate(sLogFile, fileSize + 512 * 1024);
|
||||||
|
} else
|
||||||
|
stat.st_size = -1;
|
||||||
|
|
||||||
for (uint32 i = 0; i < sCurrentEntry; i++) {
|
for (uint32 i = 0; i < sCurrentEntry; i++) {
|
||||||
cache_log *log = &sLogEntries[i];
|
cache_log *log = &sLogEntries[i];
|
||||||
char line[1536];
|
char line[1536];
|
||||||
@ -179,11 +220,12 @@ log_writer_daemon(void *arg, int /*iteration*/)
|
|||||||
|
|
||||||
switch (log->action) {
|
switch (log->action) {
|
||||||
case 'l': // launch
|
case 'l': // launch
|
||||||
length = snprintf(line, sizeof(line), "%ld: %Ld \"%s\" l ",
|
length = snprintf(line, sizeof(line), "%ld: %Ld \"%s\" l %ld \"%s\" ",
|
||||||
log->team, log->timestamp, log->team_name);
|
log->team, log->timestamp, log->team_name,
|
||||||
|
log->launch.parent, log->launch.args[0]);
|
||||||
|
|
||||||
for (int32 j = 0; j < log->args.count; j++) {
|
for (int32 j = 1; j < log->launch.arg_count; j++) {
|
||||||
strlcat(line, log->args.array[j], sizeof(line));
|
strlcat(line, log->launch.args[j], sizeof(line));
|
||||||
length = strlcat(line, " ", sizeof(line));
|
length = strlcat(line, " ", sizeof(line));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,9 +252,14 @@ log_writer_daemon(void *arg, int /*iteration*/)
|
|||||||
if (written != length) {
|
if (written != length) {
|
||||||
dprintf("log: must drop log entries: %ld, %s!\n", written, strerror(written));
|
dprintf("log: must drop log entries: %ld, %s!\n", written, strerror(written));
|
||||||
break;
|
break;
|
||||||
}
|
} else
|
||||||
|
fileSize += length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shrink file again to its real size
|
||||||
|
if (stat.st_size != -1)
|
||||||
|
ftruncate(sLogFile, fileSize);
|
||||||
|
|
||||||
// need to free any launch log items (also if writing fails)
|
// need to free any launch log items (also if writing fails)
|
||||||
|
|
||||||
for (uint32 i = 0; i < sCurrentEntry; i++) {
|
for (uint32 i = 0; i < sCurrentEntry; i++) {
|
||||||
@ -220,10 +267,10 @@ log_writer_daemon(void *arg, int /*iteration*/)
|
|||||||
if (log->action != 'l')
|
if (log->action != 'l')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (int32 j = 0; j < log->args.count; j++)
|
for (int32 j = 0; j < log->launch.arg_count; j++)
|
||||||
free(log->args.array[j]);
|
free(log->launch.args[j]);
|
||||||
|
|
||||||
free(log->args.array);
|
free(log->launch.args);
|
||||||
}
|
}
|
||||||
|
|
||||||
release_sem_etc(sLogEntrySem, sCurrentEntry, B_DO_NOT_RESCHEDULE);
|
release_sem_etc(sLogEntrySem, sCurrentEntry, B_DO_NOT_RESCHEDULE);
|
||||||
|
Loading…
Reference in New Issue
Block a user