Predicting failures in multi-tier distributed systems