Skip to content

Log deletion#4

Open
dyrock wants to merge 2 commits intomasterfrom
log_deletion
Open

Log deletion#4
dyrock wants to merge 2 commits intomasterfrom
log_deletion

Conversation

@dyrock
Copy link
Owner

@dyrock dyrock commented Sep 6, 2018

Small logs that rotate more frequently are wiped out and the loss of diagnostic logs make it harder to debug. This pull request brings a new deletion mechanism with a config option of max space allowed for all types of log files. (proxy.config.log.auto_delete_files_space_limits_mb)

The deletion will happen on the oldest file from the log type with biggest ratio=(total size used by the type)/(max space allowed for the type). Log types that are not configured with the max space allowed will not be considered for deletion. (If the config option is empty, then traffic server won't delete any files.)

Test case:
Config:
proxy.config.log.max_space_mb_for_logs INT 25
proxy.config.log.auto_delete_files_space_limits_mb STRING diags.log=7,traffic.out=8,squid.log=10
Files:
10 traffic.out (1M each), 10 diags.log (1M each), and 10 squid.log (5M each)

Verified that 1) it does delete files and 2) deletion happens in order and 3) deletion works not just for the first time.

….log (5M each) with settings proxy.config.log.auto_delete_files_max_space_mb STRING diags.log=7,traffic.out=8,squid.log=10 proxy.config.log.max_space_mb_for_logs INT 25. Verified that 1) it does delete files and 2) deletion happens in order and 3) deletion works not just for the first time.
rolling_enabled = Log::NO_ROLLING;
}

char *limits = REC_ConfigReadString("proxy.config.log.auto_delete_files_space_limits_mb");

Choose a reason for hiding this comment

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

Better to use ats_scoped_str in cases like this.

// Build new LogDeletingInfo based on the [type]=[limit] pair
deleting_info.insert(new LogDeletingInfo(key, static_cast<int64_t>(ts::svtoi(value)) * LOG_MEGABYTE));
} else {
Warning("invalid key-value pair '%s' for '%s', skipping this pair", value.data(),

Choose a reason for hiding this comment

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

Have you tested this? Can you depend on value.data() to be null terminated?

// then add this entry to the candidate list
// then check if the candidate belongs to any given log types with allowable space
//
int len = strchr(strchr(entry->d_name, '.') + 1, '.') - entry->d_name;

Choose a reason for hiding this comment

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

Why not use TextView here? This assumes the presence of '.' twice and will crash if that's not the case. Maybe

type_name = TextView(entry->d_name, strlen(entry->d_name));
type.name.remove_suffix(TextView(type_name).take_prefix_at('.').take_prefix_at('.')).size());

Alternatively, if it's really the suffix you want to remove, e.g. the name is "A.B.C" and you want "A.B", then

TextView type_name(entry->d_name, strlen(entry->d_name));
type_name.take_suffix_at('.');


iter->total_size += candidates[candidate_count].size;
candidate_count++;
total_candidate_count++;

Choose a reason for hiding this comment

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

++total_candidate_count;

-------------------------------------------------------------------------*/
struct LogDeleteCandidate {
time_t mtime;
char *name;

Choose a reason for hiding this comment

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

Rather than the explicit cleanup, make this a std::string.

int candidate_count{0};
int victim{0};
int64_t total_size{0LL};
LogDeleteCandidate candidates[MAX_CANDIDATES];

Choose a reason for hiding this comment

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

What happens if this is a std::vector? Is there a problem with iterator stability?

}

//
for (auto iter = deleting_info.begin(); iter != deleting_info.end(); iter++) {

Choose a reason for hiding this comment

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

If you're using IntrusiveHashMap, IntrusiveHashMap::apply is a better choice. Also, should you be deleting the entries in the table?

candidate_count++;
ts::TextView type_name(entry->d_name, strlen(entry->d_name));
auto suffix = type_name;
type_name.remove_suffix(suffix.remove_prefix(suffix.find('.') + 1).remove_prefix(suffix.find('.')).size());

Choose a reason for hiding this comment

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

This seems rather convoluted. Why not

suffix.take_prefix_at('.');
suffix.take_prefix_at('.');
type_name.remove_suffix(suffix.size());

or if vertical space is short

type_name.remove_suffix((suffix.take_prefix_at('.'), suffix.take_prefix_at('.'), suffix.size()));

@SolidWallOfCode
Copy link

Seems close enough.

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.

2 participants